mirror of
https://github.com/Team4388/RidgeScout.git
synced 2026-06-09 08:38:03 -06:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5a644c6671 | |||
| 05a40e39c3 | |||
| 090a0579b9 | |||
| a30664000c | |||
| 1bae273abd | |||
| 5c2b1fef2e | |||
| dbba56e649 | |||
| 4aa31b620d | |||
| 890b879ef9 |
@@ -28,9 +28,9 @@
|
||||
- Statbotics intgration
|
||||
- Scout error estimation using OPR-like calculation
|
||||
- - Would most likely require Statbotics
|
||||
|
||||
https://www.thebluealliance.com/avatars
|
||||
### Screenshots
|
||||
|Match scouting interface|Field editor|Teams data viewer|
|
||||
|-|-|-|
|
||||
||||
|
||||
|
||||
z
|
||||
@@ -57,19 +57,21 @@ dependencies {
|
||||
implementation(libs.constraintlayout)
|
||||
implementation(libs.lifecycle.livedata.ktx)
|
||||
implementation(libs.lifecycle.viewmodel.ktx)
|
||||
implementation("androidx.navigation:navigation-fragment:2.8.9")
|
||||
implementation(libs.navigation.fragment.v289)
|
||||
implementation(libs.navigation.ui)
|
||||
implementation(libs.preference)
|
||||
// implementation(libs.support.annotations)
|
||||
// implementation(libs.asynclayoutinflator)
|
||||
|
||||
testImplementation(libs.junit)
|
||||
|
||||
androidTestImplementation(libs.ext.junit)
|
||||
androidTestImplementation(libs.espresso.core)
|
||||
|
||||
|
||||
var camerax_version = "1.3.2"
|
||||
implementation("androidx.camera:camera-core:1.3.2")
|
||||
implementation("androidx.camera:camera-camera2:1.3.2")
|
||||
implementation("androidx.camera:camera-lifecycle:1.3.2")
|
||||
var camerax_version = "1.4.2"
|
||||
implementation("androidx.camera:camera-core:${camerax_version}")
|
||||
implementation("androidx.camera:camera-camera2:${camerax_version}")
|
||||
implementation("androidx.camera:camera-lifecycle:${camerax_version}")
|
||||
implementation("androidx.camera:camera-view:${camerax_version}")
|
||||
|
||||
implementation("com.journeyapps:zxing-android-embedded:4.3.0")
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.ridgebotics.ridgescout.types;
|
||||
|
||||
public class ColabArray {
|
||||
}
|
||||
@@ -9,14 +9,13 @@ import com.ridgebotics.ridgescout.utility.ByteBuilder;
|
||||
import com.ridgebotics.ridgescout.utility.SettingsManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
// Class to contain data for an entire event.
|
||||
// Easily encoded and decoded to binary format.
|
||||
public class frcEvent {
|
||||
|
||||
public static final int typecode = 254;
|
||||
public String eventCode;
|
||||
public String name;
|
||||
public ArrayList<frcMatch> matches;
|
||||
@@ -134,29 +133,29 @@ public class frcEvent {
|
||||
return null;
|
||||
}
|
||||
|
||||
// public
|
||||
|
||||
// Returns the soonest match that there will be all the possible upcoming data on other teams
|
||||
public void getReportMatches(int ourTeamNum){
|
||||
frcMatch[] teamMatches = event.getTeamMatches(ourTeamNum);
|
||||
public int getMostInformedBy(int ourTeamNum, int curMatch){
|
||||
frcMatch teamMatch = getNextTeamMatch(ourTeamNum, curMatch);
|
||||
|
||||
for(int i = 0; i < teamMatches.length; i++){
|
||||
int maxMatch = -1;
|
||||
for(int a = 0; a < 6; a++){
|
||||
int teamNum;
|
||||
if(a < 3)
|
||||
teamNum = teamMatches[i].redAlliance[a];
|
||||
else
|
||||
teamNum = teamMatches[i].blueAlliance[a-3];
|
||||
int maxMatch = Integer.MIN_VALUE;
|
||||
|
||||
if(teamNum == ourTeamNum)
|
||||
continue;
|
||||
for(int a = 0; a < 6; a++){
|
||||
int teamNum;
|
||||
if(a < 3)
|
||||
teamNum = teamMatch.redAlliance[a];
|
||||
else
|
||||
teamNum = teamMatch.blueAlliance[a-3];
|
||||
|
||||
int matchNum = event.getMostRecentTeamMatch(teamNum, teamMatches[i].matchIndex);
|
||||
if(maxMatch < matchNum)
|
||||
maxMatch = matchNum;
|
||||
}
|
||||
if(teamNum == ourTeamNum)
|
||||
continue;
|
||||
|
||||
int matchNum = event.getMostRecentTeamMatch(teamNum, teamMatch.matchIndex);
|
||||
if(maxMatch < matchNum)
|
||||
maxMatch = matchNum;
|
||||
}
|
||||
|
||||
return maxMatch;
|
||||
}
|
||||
|
||||
public frcTeam getTeamByNum(int teamNum){
|
||||
@@ -168,6 +167,26 @@ public class frcEvent {
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<frcTeam> getTeamsSorted() {
|
||||
int[] teamNums = new int[teams.size()];
|
||||
|
||||
for(int i = 0 ; i < teams.size(); i++){
|
||||
teamNums[i] = teams.get(i).teamNumber;
|
||||
}
|
||||
|
||||
Arrays.sort(teamNums);
|
||||
|
||||
List<frcTeam> list = new ArrayList<>();
|
||||
|
||||
for(int i = 0; i < teams.size(); i++){
|
||||
frcTeam team = getTeamByNum(teamNums[i]);
|
||||
assert team != null;
|
||||
list.add(team);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public boolean getIsBlueAlliance(int teamNum, int matchNum){
|
||||
return getIsBlueAlliance(teamNum, matches.get(matchNum));
|
||||
|
||||
@@ -19,9 +19,12 @@ import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.ridgebotics.ridgescout.R;
|
||||
import com.ridgebotics.ridgescout.types.frcTeam;
|
||||
import com.ridgebotics.ridgescout.ui.views.FieldBorderedRow;
|
||||
import com.ridgebotics.ridgescout.ui.views.RecyclerList;
|
||||
import com.ridgebotics.ridgescout.ui.views.TeamListOption;
|
||||
import com.ridgebotics.ridgescout.utility.DataManager;
|
||||
import com.ridgebotics.ridgescout.utility.SettingsManager;
|
||||
@@ -44,7 +47,7 @@ public class DataFragment extends Fragment {
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
|
||||
binding = FragmentDataBinding.inflate(inflater, container, false);
|
||||
binding.table.setStretchAllColumns(true);
|
||||
// binding.table.setStretchAllColumns(true);
|
||||
View root = binding.getRoot();
|
||||
|
||||
if(evcode == null || evcode.equals("unset") || event == null){
|
||||
@@ -86,35 +89,21 @@ public class DataFragment extends Fragment {
|
||||
|
||||
public void load_teams(){
|
||||
|
||||
int[] teamNums = new int[event.teams.size()];
|
||||
RecyclerList<frcTeam> list = new RecyclerList<>(getContext());
|
||||
binding.table.addView(list);
|
||||
// list.setView
|
||||
|
||||
for(int i = 0 ; i < event.teams.size(); i++){
|
||||
teamNums[i] = event.teams.get(i).teamNumber;
|
||||
}
|
||||
|
||||
Arrays.sort(teamNums);
|
||||
|
||||
for(int i = 0; i < event.teams.size(); i++){
|
||||
frcTeam team = null;
|
||||
for(int a = 0 ; a < event.teams.size(); a++){
|
||||
if(event.teams.get(a).teamNumber == teamNums[i]){
|
||||
team = event.teams.get(a);
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert team != null;
|
||||
|
||||
TeamListOption teamRow = new TeamListOption(getContext());
|
||||
binding.table.addView(teamRow);
|
||||
teamRow.fromTeam(team);
|
||||
|
||||
frcTeam finalTeam = team;
|
||||
teamRow.setOnClickListener(v -> {
|
||||
TeamsFragment.setTeam(finalTeam);
|
||||
list
|
||||
.setup(R.layout.view_team_option, TeamListOption::new)
|
||||
.withLinearLayout()
|
||||
.withDivider()
|
||||
.withItemClickListener((team, position) -> {
|
||||
TeamsFragment.setTeam(team);
|
||||
((DataParentFragment) getParentFragment()).moveToFragment(new TeamsFragment());
|
||||
// findNavController(this).navigate(R.id.action_navigation_data_parent_to_navigation_data_teams);
|
||||
});
|
||||
}
|
||||
|
||||
list.setItems(event.getTeamsSorted());
|
||||
|
||||
}
|
||||
public void load_fields(){
|
||||
DataManager.reload_match_fields();
|
||||
|
||||
@@ -20,6 +20,7 @@ import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.google.android.material.divider.MaterialDivider;
|
||||
import com.ridgebotics.ridgescout.ui.views.PitScoutingIndicator;
|
||||
import com.ridgebotics.ridgescout.ui.views.ToggleTitleView;
|
||||
import com.ridgebotics.ridgescout.utility.AlertManager;
|
||||
import com.ridgebotics.ridgescout.utility.SettingsManager;
|
||||
@@ -76,7 +77,6 @@ public class PitScoutingFragment extends Fragment {
|
||||
|
||||
String fileUsernames = "";
|
||||
ToggleTitleView[] titles;
|
||||
|
||||
AutoSaveManager asm = new AutoSaveManager(this::save, AUTO_SAVE_DELAY);
|
||||
|
||||
ArrayList<RawDataType> rawDataTypes;
|
||||
@@ -99,7 +99,7 @@ public class PitScoutingFragment extends Fragment {
|
||||
}
|
||||
|
||||
public void set_indicator_color(int color){
|
||||
binding.pitFileIndicator.setBackgroundColor(color);
|
||||
binding.pitIndicator.setColor(color);
|
||||
}
|
||||
|
||||
public void update_asm(){
|
||||
@@ -114,10 +114,9 @@ public class PitScoutingFragment extends Fragment {
|
||||
public void loadTeam(){
|
||||
// clear_fields();
|
||||
|
||||
binding.pitFileIndicator.setVisibility(View.VISIBLE);
|
||||
binding.pitsTeamCard.setVisibility(View.VISIBLE);
|
||||
binding.pitBarTeamNum.setText(String.valueOf(team.teamNumber));
|
||||
binding.pitUsername.setText(SettingsManager.getUsername());
|
||||
binding.pitIndicator.setTeamNum(team.teamNumber);
|
||||
binding.pitIndicator.setUsername(SettingsManager.getUsername());
|
||||
binding.pitsTeamCard.fromTeam(team);
|
||||
|
||||
filename = evcode + "-" + team.teamNumber + ".pitscoutdata";
|
||||
@@ -146,7 +145,7 @@ public class PitScoutingFragment extends Fragment {
|
||||
}
|
||||
}
|
||||
|
||||
binding.pitFileIndicator.bringToFront();
|
||||
binding.pitIndicator.bringToFront();
|
||||
|
||||
asm.start();
|
||||
|
||||
@@ -154,7 +153,7 @@ public class PitScoutingFragment extends Fragment {
|
||||
|
||||
private void enableRescoutButton(){
|
||||
set_indicator_color(rescout ? rescout_color : saved_color);
|
||||
binding.pitFileIndicator.setOnLongClickListener(v -> {
|
||||
binding.pitIndicator.setOnLongClickListener(v -> {
|
||||
rescout = !rescout;
|
||||
if(rescout){
|
||||
set_indicator_color(rescout_color);
|
||||
@@ -171,7 +170,7 @@ public class PitScoutingFragment extends Fragment {
|
||||
}
|
||||
|
||||
private void disableRescoutButton(){
|
||||
binding.pitFileIndicator.setOnLongClickListener(null);
|
||||
binding.pitIndicator.setOnLongClickListener(null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -51,89 +51,89 @@ public class PitSelectorFragment extends Fragment {
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
load_teams();
|
||||
// load_teams();
|
||||
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
public void load_teams(){
|
||||
// binding.pitFileIndicator.setVisibility(View.GONE);
|
||||
// binding.pitTeamName.setVisibility(View.GONE);
|
||||
// binding.pitTeamDescription.setVisibility(View.GONE);
|
||||
// public void load_teams(){
|
||||
//// binding.pitFileIndicator.setVisibility(View.GONE);
|
||||
//// binding.pitTeamName.setVisibility(View.GONE);
|
||||
//// binding.pitTeamDescription.setVisibility(View.GONE);
|
||||
////
|
||||
//// clear_fields();
|
||||
//
|
||||
// clear_fields();
|
||||
|
||||
|
||||
int[] teamNums = new int[event.teams.size()];
|
||||
|
||||
for(int i = 0 ; i < event.teams.size(); i++){
|
||||
teamNums[i] = event.teams.get(i).teamNumber;
|
||||
}
|
||||
|
||||
Arrays.sort(teamNums);
|
||||
|
||||
TableLayout table = new TableLayout(getContext());
|
||||
table.setStretchAllColumns(true);
|
||||
binding.teams.addView(table);
|
||||
|
||||
|
||||
for(int i = 0; i < event.teams.size(); i++){
|
||||
frcTeam team = null;
|
||||
for(int a = 0 ; a < event.teams.size(); a++){
|
||||
if(event.teams.get(a).teamNumber == teamNums[i]){
|
||||
team = event.teams.get(a);
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert team != null;
|
||||
|
||||
// TableRow tr = new TableRow(getContext());
|
||||
// TableLayout.LayoutParams rowParams = new TableLayout.LayoutParams(
|
||||
// FrameLayout.LayoutParams.WRAP_CONTENT,
|
||||
// FrameLayout.LayoutParams.WRAP_CONTENT
|
||||
// );
|
||||
// rowParams.setMargins(20,20,20,20);
|
||||
// tr.setLayoutParams(rowParams);
|
||||
// tr.setPadding(20,20,20,20);
|
||||
// table.addView(tr);
|
||||
|
||||
TeamListOption teamRow = new TeamListOption(getContext());
|
||||
table.addView(teamRow);
|
||||
teamRow.fromTeam(team);
|
||||
|
||||
|
||||
String filename = evcode + "-" + team.teamNumber + ".pitscoutdata";
|
||||
|
||||
if (FileEditor.fileExist(filename)) {
|
||||
final boolean[] rescout = {DataManager.rescout_list.contains(filename)};
|
||||
|
||||
teamRow.setColor(DataManager.rescout_list.contains(filename) ? color_rescout : color_found);
|
||||
|
||||
teamRow.setOnLongClickListener(v -> {
|
||||
rescout[0] = !rescout[0];
|
||||
if(rescout[0]){
|
||||
DataManager.rescout_list.add(filename);
|
||||
teamRow.setColor(color_rescout);
|
||||
DataManager.save_rescout_list();
|
||||
}else{
|
||||
DataManager.rescout_list.remove(filename);
|
||||
teamRow.setColor(color_found);
|
||||
DataManager.save_rescout_list();
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
});
|
||||
} else {
|
||||
teamRow.setColor(color_not_found);
|
||||
teamRow.setOnLongClickListener(v -> true);
|
||||
}
|
||||
|
||||
|
||||
frcTeam finalTeam = team;
|
||||
teamRow.setOnClickListener(v -> onSelect.onSelect(this, finalTeam));
|
||||
}
|
||||
}
|
||||
//
|
||||
// int[] teamNums = new int[event.teams.size()];
|
||||
//
|
||||
// for(int i = 0 ; i < event.teams.size(); i++){
|
||||
// teamNums[i] = event.teams.get(i).teamNumber;
|
||||
// }
|
||||
//
|
||||
// Arrays.sort(teamNums);
|
||||
//
|
||||
// TableLayout table = new TableLayout(getContext());
|
||||
// table.setStretchAllColumns(true);
|
||||
// binding.teams.addView(table);
|
||||
//
|
||||
//
|
||||
// for(int i = 0; i < event.teams.size(); i++){
|
||||
// frcTeam team = null;
|
||||
// for(int a = 0 ; a < event.teams.size(); a++){
|
||||
// if(event.teams.get(a).teamNumber == teamNums[i]){
|
||||
// team = event.teams.get(a);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// assert team != null;
|
||||
//
|
||||
//// TableRow tr = new TableRow(getContext());
|
||||
//// TableLayout.LayoutParams rowParams = new TableLayout.LayoutParams(
|
||||
//// FrameLayout.LayoutParams.WRAP_CONTENT,
|
||||
//// FrameLayout.LayoutParams.WRAP_CONTENT
|
||||
//// );
|
||||
//// rowParams.setMargins(20,20,20,20);
|
||||
//// tr.setLayoutParams(rowParams);
|
||||
//// tr.setPadding(20,20,20,20);
|
||||
//// table.addView(tr);
|
||||
//
|
||||
// TeamListOption teamRow = new TeamListOption(getContext());
|
||||
// table.addView(teamRow);
|
||||
// teamRow.fromTeam(team);
|
||||
//
|
||||
//
|
||||
// String filename = evcode + "-" + team.teamNumber + ".pitscoutdata";
|
||||
//
|
||||
// if (FileEditor.fileExist(filename)) {
|
||||
// final boolean[] rescout = {DataManager.rescout_list.contains(filename)};
|
||||
//
|
||||
// teamRow.setColor(DataManager.rescout_list.contains(filename) ? color_rescout : color_found);
|
||||
//
|
||||
// teamRow.setOnLongClickListener(v -> {
|
||||
// rescout[0] = !rescout[0];
|
||||
// if(rescout[0]){
|
||||
// DataManager.rescout_list.add(filename);
|
||||
// teamRow.setColor(color_rescout);
|
||||
// DataManager.save_rescout_list();
|
||||
// }else{
|
||||
// DataManager.rescout_list.remove(filename);
|
||||
// teamRow.setColor(color_found);
|
||||
// DataManager.save_rescout_list();
|
||||
// }
|
||||
//
|
||||
//
|
||||
// return true;
|
||||
// });
|
||||
// } else {
|
||||
// teamRow.setColor(color_not_found);
|
||||
// teamRow.setOnLongClickListener(v -> true);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// frcTeam finalTeam = team;
|
||||
// teamRow.setOnClickListener(v -> onSelect.onSelect(this, finalTeam));
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -89,7 +90,7 @@ public class ScoutingFragment extends Fragment {
|
||||
|
||||
binding.textMatchAlliance.setVisibility(View.GONE);
|
||||
binding.textName.setVisibility(View.GONE);
|
||||
binding.textNextMatch.setVisibility(View.GONE);
|
||||
binding.infoBox.setVisibility(View.GONE);
|
||||
binding.textRescoutIndicator.setVisibility(View.GONE);
|
||||
|
||||
binding.matchScoutingButton.setEnabled(false);
|
||||
@@ -123,20 +124,7 @@ public class ScoutingFragment extends Fragment {
|
||||
findNavController(this).navigate(R.id.action_navigation_scouting_to_navigation_scouting_event);
|
||||
});
|
||||
|
||||
|
||||
binding.textName.setText("Welcome, " + SettingsManager.getUsername() + "!");
|
||||
|
||||
int matchNum = SettingsManager.getMatchNum();
|
||||
int nextMatch = -1;
|
||||
try {
|
||||
nextMatch = event.getNextTeamMatch(SettingsManager.getTeamNum(), matchNum).matchIndex;
|
||||
} catch (Exception e){
|
||||
AlertManager.error(e);
|
||||
}
|
||||
|
||||
binding.textNextMatch.setText("Our next match: Match " + nextMatch);
|
||||
binding.textMatchAlliance.setText("Match: " + (matchNum+1) + ", " + SettingsManager.getAllyPos());
|
||||
binding.textRescoutIndicator.setText("Things to rescout: " + DataManager.rescout_list.size());
|
||||
updateDashboard();
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
@@ -165,4 +153,32 @@ public class ScoutingFragment extends Fragment {
|
||||
});
|
||||
}
|
||||
|
||||
private void updateDashboard() {
|
||||
binding.textName.setText("Welcome, " + SettingsManager.getUsername() + "!");
|
||||
|
||||
int curMatchNum = SettingsManager.getMatchNum();
|
||||
int nextMatch;
|
||||
int teamNum = SettingsManager.getTeamNum();
|
||||
try {
|
||||
nextMatch = event.getNextTeamMatch(teamNum, curMatchNum).matchIndex;
|
||||
} catch (Exception e){
|
||||
AlertManager.error("Sorry, in event ("+evcode+"), your team number ("+teamNum+") wasn't found!", e);
|
||||
return;
|
||||
}
|
||||
|
||||
binding.textMatchAlliance.setText("Match: " + (curMatchNum+1) + ", " + SettingsManager.getAllyPos());
|
||||
binding.textRescoutIndicator.setText("Things to rescout: " + DataManager.rescout_list.size());
|
||||
|
||||
TextView nextMatchText = new TextView(getContext());
|
||||
nextMatchText.setText("Our next match: Match " + nextMatch);
|
||||
nextMatchText.setTextAppearance(com.google.android.material.R.style.TextAppearance_MaterialComponents_Body1);
|
||||
binding.infoBox.addView(nextMatchText);
|
||||
|
||||
int informedBy = event.getMostInformedBy(teamNum, curMatchNum);
|
||||
|
||||
TextView mostInformedText = new TextView(getContext());
|
||||
mostInformedText.setText("Most informed by: Match " + informedBy);
|
||||
mostInformedText.setTextAppearance(com.google.android.material.R.style.TextAppearance_MaterialComponents_Body1);
|
||||
binding.infoBox.addView(mostInformedText);
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.navigation.Navigation;
|
||||
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.ridgebotics.ridgescout.MainActivity;
|
||||
import com.ridgebotics.ridgescout.R;
|
||||
import com.ridgebotics.ridgescout.databinding.FragmentSettingsFieldsBinding;
|
||||
@@ -216,7 +217,7 @@ public class FieldsFragment extends Fragment {
|
||||
AlertDialog dialog = alert.create();
|
||||
dialog.show();
|
||||
|
||||
Button deleteButton = new Button(getContext());
|
||||
MaterialButton deleteButton = new MaterialButton(getContext());
|
||||
deleteButton.setText("DELETE");
|
||||
deleteButton.setOnClickListener(l -> {
|
||||
AlertDialog.Builder alert2 = new AlertDialog.Builder(getContext());
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.ridgebotics.ridgescout.ui.settings;
|
||||
|
||||
import static android.view.View.VISIBLE;
|
||||
import static android.widget.LinearLayout.HORIZONTAL;
|
||||
import static android.widget.LinearLayout.VERTICAL;
|
||||
import static androidx.navigation.fragment.FragmentKt.findNavController;
|
||||
import static com.ridgebotics.ridgescout.utility.SettingsManager.AllyPosKey;
|
||||
import static com.ridgebotics.ridgescout.utility.SettingsManager.CustomEventsKey;
|
||||
@@ -13,6 +15,7 @@ import static com.ridgebotics.ridgescout.utility.SettingsManager.UnameKey;
|
||||
import static com.ridgebotics.ridgescout.utility.SettingsManager.WifiModeKey;
|
||||
import static com.ridgebotics.ridgescout.utility.SettingsManager.YearNumKey;
|
||||
import static com.ridgebotics.ridgescout.utility.SettingsManager.defaults;
|
||||
import static com.ridgebotics.ridgescout.utility.SettingsManager.getEVCode;
|
||||
import static com.ridgebotics.ridgescout.utility.SettingsManager.getEditor;
|
||||
import static com.ridgebotics.ridgescout.utility.SettingsManager.prefs;
|
||||
|
||||
@@ -30,13 +33,17 @@ import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TableLayout;
|
||||
import android.widget.TableRow;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.google.android.material.checkbox.MaterialCheckBox;
|
||||
import com.google.android.material.divider.MaterialDivider;
|
||||
import com.google.android.material.textfield.TextInputEditText;
|
||||
import com.google.android.material.textfield.TextInputLayout;
|
||||
import com.ridgebotics.ridgescout.R;
|
||||
@@ -48,6 +55,8 @@ import com.ridgebotics.ridgescout.utility.DataManager;
|
||||
import com.ridgebotics.ridgescout.utility.FileEditor;
|
||||
import com.ridgebotics.ridgescout.utility.SettingsManager;
|
||||
|
||||
import org.w3c.dom.Text;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
@@ -65,20 +74,6 @@ public class SettingsFragment extends Fragment {
|
||||
|
||||
reloadSettings();
|
||||
|
||||
binding.fieldsButton.setOnClickListener(v -> {
|
||||
binding.fieldsButton.setEnabled(false);
|
||||
binding.fieldsButtons.setVisibility(VISIBLE);
|
||||
});
|
||||
|
||||
binding.fieldsMatchesButton.setOnClickListener(v -> {
|
||||
FieldsFragment.set_filename(Fields.matchFieldsFilename);
|
||||
findNavController(this).navigate(R.id.action_navigation_settings_to_navigation_data_fields);
|
||||
});
|
||||
|
||||
binding.fieldsPitsButton.setOnClickListener(v -> {
|
||||
FieldsFragment.set_filename(Fields.pitsFieldsFilename);
|
||||
findNavController(this).navigate(R.id.action_navigation_settings_to_navigation_data_fields);
|
||||
});
|
||||
|
||||
|
||||
return root;
|
||||
@@ -91,28 +86,67 @@ public class SettingsFragment extends Fragment {
|
||||
SettingsManager manager = new SettingsManager(getContext());
|
||||
|
||||
|
||||
|
||||
ButtonSettingsItem corruptButton = new ButtonSettingsItem();
|
||||
corruptButton.addButton("Remove corrupted files", view -> {});
|
||||
|
||||
manager.addItem(corruptButton);
|
||||
manager.addItem(new HeaderSettingsItem("Advanced"));
|
||||
|
||||
|
||||
|
||||
|
||||
ButtonSettingsItem fieldsButtons = new ButtonSettingsItem();
|
||||
fieldsButtons.addButton("Edit pit fields", v -> {
|
||||
FieldsFragment.set_filename(Fields.pitsFieldsFilename);
|
||||
findNavController(this).navigate(R.id.action_navigation_settings_to_navigation_data_fields);
|
||||
});
|
||||
fieldsButtons.addButton("Edit match fields", v -> {
|
||||
FieldsFragment.set_filename(Fields.matchFieldsFilename);
|
||||
findNavController(this).navigate(R.id.action_navigation_settings_to_navigation_data_fields);
|
||||
});
|
||||
manager.addItem(fieldsButtons);
|
||||
|
||||
ButtonSettingsItem noticeButton = new ButtonSettingsItem();
|
||||
noticeButton.addButton("Edit scout notice", v->editNotice());
|
||||
noticeButton.setEnabled(!getEVCode().equals("unset"));
|
||||
manager.addItem(noticeButton);
|
||||
|
||||
|
||||
manager.addItem(new CheckboxSettingsItem(CustomEventsKey, "Custom Events"));
|
||||
|
||||
CheckboxSettingsItem FTPSendMetaFiles = new CheckboxSettingsItem(com.ridgebotics.ridgescout.utility.SettingsManager.FTPSendMetaFiles, "[⚠] Send meta files");
|
||||
manager.addItem(FTPSendMetaFiles);
|
||||
|
||||
manager.addItem(new HeaderSettingsItem("Admin"));
|
||||
|
||||
|
||||
|
||||
|
||||
StringSettingsItem FTPKey = new StringSettingsItem(com.ridgebotics.ridgescout.utility.SettingsManager.FTPKey, "Sync Key");
|
||||
manager.addItem(FTPKey);
|
||||
StringSettingsItem FTPServer = new StringSettingsItem(com.ridgebotics.ridgescout.utility.SettingsManager.FTPServer, "Sync Server (Sync)");
|
||||
manager.addItem(FTPServer);
|
||||
CheckboxSettingsItem FTPSendMetaFiles = new CheckboxSettingsItem(com.ridgebotics.ridgescout.utility.SettingsManager.FTPSendMetaFiles, "⚠ Send meta files");
|
||||
manager.addItem(FTPSendMetaFiles);
|
||||
CheckboxSettingsItem FTPEnabled = new CheckboxSettingsItem(com.ridgebotics.ridgescout.utility.SettingsManager.FTPEnabled, "FTP Enabled", FTPServer, FTPKey, FTPSendMetaFiles);
|
||||
CheckboxSettingsItem FTPEnabled = new CheckboxSettingsItem(com.ridgebotics.ridgescout.utility.SettingsManager.FTPEnabled, "Sync Enabled", FTPServer, FTPKey, FTPSendMetaFiles);
|
||||
manager.addItem(FTPEnabled);
|
||||
|
||||
manager.addItem(new CheckboxSettingsItem(WifiModeKey, "Wifi Mode", FTPEnabled));
|
||||
manager.addItem(new CheckboxSettingsItem(EnableQuickAllianceChangeKey, "Enable quick alliance swap", null));
|
||||
|
||||
|
||||
manager.addItem(new NumberSettingsItem(YearNumKey, "Year", 0, 9999));
|
||||
|
||||
manager.addItem(new HeaderSettingsItem("Connection"));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
manager.addItem(new CheckboxSettingsItem(EnableQuickAllianceChangeKey, "Enable quick alliance swap", null));
|
||||
manager.addItem(new DropdownSettingsItem(FieldImageKey, "Field Image", new String[]{
|
||||
"2025",
|
||||
"2025 (Flipped)"
|
||||
}));
|
||||
|
||||
manager.addItem(new NumberSettingsItem(YearNumKey, "Year", 0, 9999));
|
||||
|
||||
|
||||
manager.addItem(new DropdownSettingsItem(AllyPosKey, "Alliance Pos", alliance_pos_list));
|
||||
|
||||
int max = 0;
|
||||
@@ -134,16 +168,48 @@ public class SettingsFragment extends Fragment {
|
||||
|
||||
manager.addItem(new StringSettingsItem(UnameKey, "Username"));
|
||||
manager.addItem(new NumberSettingsItem(TeamNumKey, "Team Number", 0, 99999));
|
||||
manager.addItem(new HeaderSettingsItem("Scouting"));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
binding.SettingsTable.removeAllViews();
|
||||
|
||||
manager.getView(binding.SettingsTable);
|
||||
|
||||
if(!DataManager.getevcode().equals("unset")){
|
||||
Button editNoticeButton = new Button(getContext());
|
||||
editNoticeButton.setText("Edit Scout Notice");
|
||||
binding.SettingsTable.addView(editNoticeButton);
|
||||
editNoticeButton.setOnClickListener(v->editNotice());
|
||||
}
|
||||
|
||||
// Add "Edit scout notice" button to the bottom of the page=
|
||||
|
||||
|
||||
// Add "Field edit" buttons to the bottom of the page
|
||||
// LinearLayout fieldButtons = new LinearLayout(getContext());
|
||||
// fieldButtons.setLayoutParams(new LinearLayout.LayoutParams(
|
||||
// LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
// LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
// ));
|
||||
// fieldButtons.setOrientation(HORIZONTAL);
|
||||
//
|
||||
// Button editMatchFieldsButton = new Button(getContext());
|
||||
// editMatchFieldsButton.setText("Edit Match Fields");
|
||||
// editMatchFieldsButton.setOnClickListener(v -> {
|
||||
// FieldsFragment.set_filename(Fields.matchFieldsFilename);
|
||||
// findNavController(this).navigate(R.id.action_navigation_settings_to_navigation_data_fields);
|
||||
// });
|
||||
// fieldButtons.addView(editMatchFieldsButton);
|
||||
//
|
||||
//
|
||||
// Button editPitsFieldsButton = new Button(getContext());
|
||||
// editPitsFieldsButton.setText("Edit pits Fields");
|
||||
// editPitsFieldsButton.setOnClickListener(v -> {
|
||||
// FieldsFragment.set_filename(Fields.pitsFieldsFilename);
|
||||
// findNavController(this).navigate(R.id.action_navigation_settings_to_navigation_data_fields);
|
||||
// });
|
||||
// fieldButtons.addView(editPitsFieldsButton);
|
||||
|
||||
|
||||
// binding.SettingsTable.addView(fieldButtons);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -347,7 +413,7 @@ public class SettingsFragment extends Fragment {
|
||||
@Override
|
||||
public View createView(Context context) {
|
||||
LinearLayout ll = new LinearLayout(getContext());
|
||||
ll.setOrientation(LinearLayout.VERTICAL);
|
||||
ll.setOrientation(VERTICAL);
|
||||
|
||||
tally = new TallyCounterView(getContext());
|
||||
|
||||
@@ -475,6 +541,94 @@ public class SettingsFragment extends Fragment {
|
||||
}
|
||||
}
|
||||
|
||||
public class HeaderSettingsItem extends SettingsItem<Void> {
|
||||
String title;
|
||||
|
||||
public HeaderSettingsItem(String title) {
|
||||
super("", title, null);
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled){
|
||||
}
|
||||
|
||||
@Override
|
||||
public View createView(Context context) {
|
||||
LinearLayout ll = new LinearLayout(context);
|
||||
ll.setOrientation(VERTICAL);
|
||||
ll.setPadding(0, 20,0,0);
|
||||
|
||||
TextView tv = new TextView(context);
|
||||
tv.setText(title);
|
||||
tv.setTextAppearance(com.google.android.material.R.style.TextAppearance_MaterialComponents_Headline4);
|
||||
ll.addView(tv);
|
||||
|
||||
ll.addView(new MaterialDivider(context));
|
||||
|
||||
return ll;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void getValue() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class ButtonSettingsItem extends SettingsItem<Void> {
|
||||
List<MaterialButton> buttons = new ArrayList<>();
|
||||
List<String> titles = new ArrayList<>();
|
||||
List<View.OnClickListener> callbacks = new ArrayList<>();
|
||||
|
||||
boolean enabled = true;
|
||||
|
||||
public ButtonSettingsItem() {
|
||||
super("", "", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled){
|
||||
this.enabled = enabled;
|
||||
for(int i = 0; i < buttons.size(); i++){
|
||||
buttons.get(i).setEnabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
public void addButton(String text, View.OnClickListener onClickListener) {
|
||||
titles.add(text);
|
||||
callbacks.add(onClickListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View createView(Context context) {
|
||||
LinearLayout ll = new LinearLayout(context);
|
||||
ll.setOrientation(HORIZONTAL);
|
||||
|
||||
for(int i = 0; i < titles.size(); i++){
|
||||
MaterialButton button = new MaterialButton(context);
|
||||
button.setText(titles.get(i));
|
||||
button.setOnClickListener(callbacks.get(i));
|
||||
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f);
|
||||
layoutParams.setMargins(3, 0, 3, 0);
|
||||
// layoutParams.weight
|
||||
button.setLayoutParams(layoutParams);
|
||||
button.setEnabled(enabled);
|
||||
// button.weight
|
||||
buttons.add(button);
|
||||
|
||||
ll.addView(button);
|
||||
}
|
||||
|
||||
return ll;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void getValue() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class SettingsManager {
|
||||
private Context context;
|
||||
private HashMap<String, Object> settings;
|
||||
@@ -497,7 +651,7 @@ public class SettingsFragment extends Fragment {
|
||||
items.add(item);
|
||||
|
||||
LinearLayout itemContainer = new LinearLayout(context);
|
||||
itemContainer.setOrientation(LinearLayout.VERTICAL);
|
||||
itemContainer.setOrientation(VERTICAL);
|
||||
itemContainer.setPadding(32, 0, 32, 8);
|
||||
|
||||
View view = item.createView(context);
|
||||
|
||||
@@ -28,7 +28,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
// This is now deprecated
|
||||
// This is now deprecated. use HTTPSync
|
||||
// Class to synchronise data over FTP.
|
||||
public class FTPSync extends Thread {
|
||||
public static final String remoteBasePath = "/RidgeScout/";
|
||||
|
||||
@@ -30,8 +30,7 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
// This is now deprsicated
|
||||
// Class to syncronise data over FTP.
|
||||
// Class to synchronise data over HTTP.
|
||||
public class HttpSync extends Thread {
|
||||
public static final String timestampsFilename = "timestamps";
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.ridgebotics.ridgescout.R;
|
||||
import com.ridgebotics.ridgescout.databinding.FragmentTransferTbaBinding;
|
||||
import com.ridgebotics.ridgescout.types.frcEvent;
|
||||
@@ -49,8 +50,6 @@ public class TBAEventFragment extends Fragment {
|
||||
|
||||
private final int year = SettingsManager.getYearNum();
|
||||
|
||||
private ProgressDialog loadingDialog;
|
||||
|
||||
private static JSONObject eventData = null;
|
||||
public static void setEventData(JSONObject j){
|
||||
eventData = j;
|
||||
@@ -74,7 +73,7 @@ public class TBAEventFragment extends Fragment {
|
||||
|
||||
Table.setStretchAllColumns(true);
|
||||
|
||||
startLoading("Loading Teams and Matches...");
|
||||
AlertManager.startLoading("Loading Teams and Matches...");
|
||||
Table.removeAllViews();
|
||||
Table.setStretchAllColumns(true);
|
||||
Table.bringToFront();
|
||||
@@ -92,7 +91,7 @@ public class TBAEventFragment extends Fragment {
|
||||
final RequestTask rq1 = new RequestTask();
|
||||
rq1.onResult(matchesStr -> {
|
||||
matchTable(matchesStr, teamsStr, eventData);
|
||||
stopLoading();
|
||||
AlertManager.stopLoading();
|
||||
return null;
|
||||
});
|
||||
rq1.execute((TBAAddress + "event/" + matchKey + "/matches"), TBAHeader);
|
||||
@@ -153,7 +152,7 @@ public class TBAEventFragment extends Fragment {
|
||||
|
||||
|
||||
// Save button
|
||||
Button btn = new Button(getContext());
|
||||
MaterialButton btn = new MaterialButton(getContext());
|
||||
btn.setText("Save");
|
||||
btn.setTextSize(18);
|
||||
btn.setLayoutParams(new TableRow.LayoutParams(
|
||||
@@ -375,12 +374,12 @@ public class TBAEventFragment extends Fragment {
|
||||
|
||||
}catch (JSONException j){
|
||||
AlertManager.error("Failed Downloading", j);
|
||||
stopLoading();
|
||||
AlertManager.stopLoading();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean saveData(ArrayList<frcMatch> matchData, JSONArray teamData, JSONObject eventData){
|
||||
startLoading("Saving data...");
|
||||
AlertManager.startLoading("Saving data...");
|
||||
|
||||
Thread t = new Thread(() -> {
|
||||
try {
|
||||
@@ -431,31 +430,15 @@ public class TBAEventFragment extends Fragment {
|
||||
AlertManager.toast("Saved!");
|
||||
|
||||
getActivity().runOnUiThread(() -> findNavController(this).navigate(R.id.action_navigation_tba_event_to_navigation_transfer));
|
||||
stopLoading();
|
||||
AlertManager.stopLoading();
|
||||
|
||||
}catch(Exception j) {
|
||||
AlertManager.error(j);
|
||||
stopLoading();
|
||||
AlertManager.stopLoading();
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void startLoading(String title){
|
||||
getActivity().runOnUiThread(() -> {
|
||||
if(loadingDialog != null && loadingDialog.isShowing())
|
||||
loadingDialog.dismiss();
|
||||
loadingDialog = ProgressDialog.show(getActivity(), title, "Please wait...");
|
||||
});
|
||||
}
|
||||
|
||||
private void stopLoading(){
|
||||
getActivity().runOnUiThread(() -> {
|
||||
if (loadingDialog != null)
|
||||
loadingDialog.cancel();
|
||||
loadingDialog = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
package com.ridgebotics.ridgescout.ui.transfer.codes;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.EncodeHintType;
|
||||
import com.google.zxing.MultiFormatWriter;
|
||||
import com.google.zxing.WriterException;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
import com.ridgebotics.ridgescout.utility.AlertManager;
|
||||
import com.ridgebotics.ridgescout.utility.FileEditor;
|
||||
import com.ridgebotics.ridgescout.utility.TaskRunner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class CodeGenTask implements Callable<List<Bitmap>> {
|
||||
// private Function<List<Bitmap>, String> resultFunction = null;
|
||||
//
|
||||
// @Override
|
||||
// protected List<Bitmap> doInBackground(String... strings) {
|
||||
//
|
||||
|
||||
//
|
||||
// return new ArrayList<>();
|
||||
// }
|
||||
//
|
||||
//
|
||||
// public void onResult(Function<List<Bitmap>, String> func) {
|
||||
// this.resultFunction = func;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// @Override
|
||||
// protected void onPostExecute(List<Bitmap> result) {
|
||||
// super.onPostExecute(result);
|
||||
// if(resultFunction != null){
|
||||
// resultFunction.apply(result);
|
||||
// }
|
||||
// }
|
||||
|
||||
private final String data;
|
||||
private final int randID;
|
||||
private final int qrSize;
|
||||
private final int qrCount;
|
||||
private final int imageSize;
|
||||
|
||||
public CodeGenTask(String data, int randID, int qrSize, int qrCount, int imageSize) {
|
||||
this.data = data;
|
||||
this.randID = randID;
|
||||
this.qrSize = qrSize;
|
||||
this.qrCount = qrCount;
|
||||
this.imageSize = imageSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Bitmap> call() {
|
||||
List<Bitmap> qrBitmaps = new ArrayList<>();
|
||||
|
||||
for(int i=0;i<=((data.length()+1)/qrSize);i++){
|
||||
final int start = i*qrSize;
|
||||
int end = (i+1)*qrSize;
|
||||
if(end >= data.length()){
|
||||
end = data.length();
|
||||
}
|
||||
try {
|
||||
Bitmap unscaledBitmap = generateQrCode(
|
||||
FileEditor.byteToChar(FileEditor.internalDataVersion, FileEditor.lengthHeaderBytes) +
|
||||
String.valueOf(FileEditor.byteToChar(randID, FileEditor.lengthHeaderBytes)) +
|
||||
FileEditor.byteToChar(i, FileEditor.lengthHeaderBytes) +
|
||||
FileEditor.byteToChar(qrCount - 1, FileEditor.lengthHeaderBytes) +
|
||||
data.substring(start, end)
|
||||
);
|
||||
if(unscaledBitmap == null) {
|
||||
AlertManager.error("Generated image was null!");
|
||||
continue;
|
||||
}
|
||||
qrBitmaps.add(Bitmap.createScaledBitmap(unscaledBitmap, imageSize, imageSize, false));
|
||||
// alert("title", ""+(qrCount-1));
|
||||
}catch (WriterException e){
|
||||
AlertManager.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
return qrBitmaps;
|
||||
}
|
||||
|
||||
private Bitmap generateQrCode(String contents) throws WriterException {
|
||||
|
||||
final int size = 512;
|
||||
|
||||
if (contents == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
|
||||
|
||||
// The Charset must be UTF-8, Or data will not be transferred properly. IDK why.
|
||||
hints.put(EncodeHintType.CHARACTER_SET, "ISO-8859-1");
|
||||
// hints.put(EncodeHintType.);
|
||||
hints.put(EncodeHintType.MARGIN, 0); /* default = 4 */
|
||||
MultiFormatWriter writer = new MultiFormatWriter();
|
||||
|
||||
BitMatrix result;
|
||||
try {
|
||||
result = writer.encode(contents, BarcodeFormat.DATA_MATRIX, size, size, hints);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Unsupported format
|
||||
AlertManager.error(e);
|
||||
return null;
|
||||
}
|
||||
|
||||
int width = result.getWidth();
|
||||
int height = result.getHeight();
|
||||
int[] pixels = new int[width * height];
|
||||
for (int y = 0; y < height; y++) {
|
||||
int offset = y * width;
|
||||
for (int x = 0; x < width; x++) {
|
||||
pixels[offset + x] = result.get(x, y) ? Color.BLACK : Color.WHITE;
|
||||
}
|
||||
}
|
||||
|
||||
Bitmap bitmap = Bitmap.createBitmap(width, height,
|
||||
Bitmap.Config.ARGB_8888);
|
||||
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
}
|
||||
+73
-107
@@ -1,9 +1,10 @@
|
||||
package com.ridgebotics.ridgescout.ui.transfer.codes;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.os.CountDownTimer;
|
||||
import android.os.Handler;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -18,16 +19,11 @@ import androidx.fragment.app.Fragment;
|
||||
import com.ridgebotics.ridgescout.databinding.FragmentTransferCodeSenderBinding;
|
||||
import com.ridgebotics.ridgescout.utility.AlertManager;
|
||||
import com.ridgebotics.ridgescout.utility.FileEditor;
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.EncodeHintType;
|
||||
import com.google.zxing.MultiFormatWriter;
|
||||
import com.google.zxing.WriterException;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
import com.ridgebotics.ridgescout.utility.TaskRunner;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
// Class to show the code transfer thing.
|
||||
@@ -38,23 +34,28 @@ public class CodeGeneratorView extends Fragment {
|
||||
private TextView qrIndexN;
|
||||
private TextView qrIndexD;
|
||||
|
||||
private final int maxQrCount = 256; //The max number that can be stored in a byte
|
||||
private static final int maxQrCount = 256; //The max number that can be stored in a byte
|
||||
|
||||
private final int maxQrSpeed = 5;
|
||||
private final int minQrSpeed = 300 + maxQrSpeed - 1;
|
||||
private static final int maxQrSize = 800;
|
||||
|
||||
|
||||
private static final int maxQrSpeed = 50;
|
||||
private static final int minQrSpeed = 1000;
|
||||
private static final int defaultQrDelay = 12;
|
||||
|
||||
|
||||
private int imageSize;
|
||||
|
||||
private int minQrSize = 0;
|
||||
private final int maxQrSize = 800;
|
||||
private int qrSize = 200;
|
||||
|
||||
private final int defaultQrDelay = 419;
|
||||
private int qrDelay = 0;
|
||||
private double qrDelay = 0;
|
||||
private int qrIndex = 0;
|
||||
|
||||
private CountDownTimer timer;
|
||||
private int qrCount = 0;
|
||||
|
||||
private ArrayList<Bitmap> qrBitmaps;
|
||||
private List<Bitmap> qrBitmaps = new ArrayList<>();
|
||||
|
||||
private FragmentTransferCodeSenderBinding binding;
|
||||
|
||||
@@ -77,6 +78,12 @@ public class CodeGeneratorView extends Fragment {
|
||||
qrIndexN = binding.qrIndexN;
|
||||
qrIndexD = binding.qrIndexD;
|
||||
|
||||
DisplayMetrics displaymetrics = new DisplayMetrics();
|
||||
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
|
||||
// int height = displaymetrics.heightPixels;
|
||||
imageSize = displaymetrics.widthPixels;
|
||||
// = 800;
|
||||
|
||||
String compressed = new String(FileEditor.blockCompress(data, FileEditor.lengthHeaderBytes), StandardCharsets.ISO_8859_1);
|
||||
|
||||
if(compressed.isEmpty()){
|
||||
@@ -85,75 +92,30 @@ public class CodeGeneratorView extends Fragment {
|
||||
}
|
||||
|
||||
minQrSize = Math.round((float)compressed.length() / maxQrCount)+1;
|
||||
|
||||
qrSizeSlider.setMax(maxQrSize-minQrSize);
|
||||
qrSpeedSlider.setMax((minQrSpeed-maxQrSpeed)*2);
|
||||
|
||||
qrSizeSlider.setProgress(minQrSize+qrSize);
|
||||
qrSpeedSlider.setProgress(defaultQrDelay+5);
|
||||
qrSize += minQrSize;
|
||||
|
||||
sendData(compressed);
|
||||
|
||||
qrSpeedSlider.setMax(maxQrSpeed*2);
|
||||
qrSpeedSlider.setProgress(maxQrSpeed + defaultQrDelay);
|
||||
|
||||
qrSizeSlider.setMax(maxQrSize-minQrSize);
|
||||
qrSizeSlider.setProgress(qrSize-minQrSize);
|
||||
|
||||
startLoop();
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
|
||||
private Bitmap generateQrCode(String contents) throws WriterException {
|
||||
|
||||
final int size = 512;
|
||||
|
||||
if (contents == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
|
||||
|
||||
// The Charset must be UTF-8, Or data will not be transferred properly. IDK why.
|
||||
hints.put(EncodeHintType.CHARACTER_SET, "ISO-8859-1");
|
||||
// hints.put(EncodeHintType.);
|
||||
hints.put(EncodeHintType.MARGIN, 0); /* default = 4 */
|
||||
MultiFormatWriter writer = new MultiFormatWriter();
|
||||
|
||||
BitMatrix result;
|
||||
try {
|
||||
result = writer.encode(contents, BarcodeFormat.DATA_MATRIX, size, size, hints);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Unsupported format
|
||||
AlertManager.error(e);
|
||||
return null;
|
||||
}
|
||||
|
||||
int width = result.getWidth();
|
||||
int height = result.getHeight();
|
||||
int[] pixels = new int[width * height];
|
||||
for (int y = 0; y < height; y++) {
|
||||
int offset = y * width;
|
||||
for (int x = 0; x < width; x++) {
|
||||
pixels[offset + x] = result.get(x, y) ? Color.BLACK : Color.WHITE;
|
||||
}
|
||||
}
|
||||
|
||||
Bitmap bitmap = Bitmap.createBitmap(width, height,
|
||||
Bitmap.Config.ARGB_8888);
|
||||
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
|
||||
private void sendData(String data){
|
||||
|
||||
|
||||
|
||||
qrCount = (data.length()/qrSize)+1;
|
||||
qrIndexD.setText(String.valueOf(qrCount));
|
||||
|
||||
// alert("size", ""+binding.qrSizeSlider.getProgress()+"\n"+binding.qrSizeSlider.getMax());
|
||||
|
||||
qrSpeedSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
qrDelay = -(minQrSpeed - progress - maxQrSpeed + 1);
|
||||
qrDelay = ((double) progress /maxQrSpeed) - 1;
|
||||
// startLoop();
|
||||
}
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
@@ -173,43 +135,24 @@ public class CodeGeneratorView extends Fragment {
|
||||
qrCount = ((data.length()+1)/qrSize) +1;
|
||||
qrIndexD.setText(String.valueOf(qrCount));
|
||||
sendData(data);
|
||||
// startLoop();
|
||||
}
|
||||
});
|
||||
|
||||
// qrSizeSlider.setProgress(qr);
|
||||
AlertManager.startLoading("Generating codes...");
|
||||
|
||||
qrBitmaps = new ArrayList<>();
|
||||
new TaskRunner().executeAsync(new CodeGenTask(data, new Random().nextInt(255), qrSize, qrCount, imageSize), result -> {
|
||||
qrBitmaps = result;
|
||||
AlertManager.stopLoading();
|
||||
qrIndex = 0;
|
||||
});
|
||||
|
||||
int randID = new Random().nextInt(255);
|
||||
|
||||
for(int i=0;i<=((data.length()+1)/qrSize);i++){
|
||||
final int start = i*qrSize;
|
||||
int end = (i+1)*qrSize;
|
||||
if(end >= data.length()){
|
||||
end = data.length();
|
||||
}
|
||||
try {
|
||||
// alert("test", ""+Math.ceil((double)data.length()/(double)qrSize));
|
||||
qrBitmaps.add(generateQrCode(
|
||||
FileEditor.byteToChar(FileEditor.internalDataVersion, FileEditor.lengthHeaderBytes) +
|
||||
String.valueOf(FileEditor.byteToChar(randID, FileEditor.lengthHeaderBytes)) +
|
||||
FileEditor.byteToChar(i, FileEditor.lengthHeaderBytes) +
|
||||
FileEditor.byteToChar(qrCount - 1, FileEditor.lengthHeaderBytes) +
|
||||
data.substring(start, end)
|
||||
));
|
||||
// alert("title", ""+(qrCount-1));
|
||||
}catch (WriterException e){
|
||||
AlertManager.error(e);
|
||||
}
|
||||
}
|
||||
qrIndex = 0;
|
||||
if(timer != null){
|
||||
timer.cancel();
|
||||
}
|
||||
qrLoop();
|
||||
}
|
||||
|
||||
private void updateQr(){
|
||||
if(qrBitmaps.isEmpty())
|
||||
return;
|
||||
|
||||
qrImage.setImageBitmap(qrBitmaps.get(qrIndex));
|
||||
if(qrDelay > 0) {
|
||||
this.qrIndex += 1;
|
||||
@@ -226,13 +169,36 @@ public class CodeGeneratorView extends Fragment {
|
||||
qrIndexN.setText(String.valueOf(qrIndex+1));
|
||||
}
|
||||
|
||||
private void qrLoop(){
|
||||
timer = new CountDownTimer(minQrSpeed-Math.abs(qrDelay)+1, 1000) {
|
||||
public void onTick(long millisUntilFinished) {}
|
||||
public void onFinish() {
|
||||
updateQr();
|
||||
qrLoop();
|
||||
private boolean shouldstop = false;
|
||||
|
||||
private void startLoop() {
|
||||
final Handler handler = new Handler();
|
||||
Runnable runnable = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if(shouldstop){
|
||||
return;
|
||||
}
|
||||
try{
|
||||
updateQr();
|
||||
}
|
||||
catch (Exception e) {
|
||||
AlertManager.error(e);
|
||||
}
|
||||
finally{
|
||||
double a = ((double) maxQrSpeed) / (Math.abs(qrDelay));
|
||||
a = Math.min(Math.max(a, maxQrSpeed), minQrSpeed);
|
||||
handler.postDelayed(this, (long) a);
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
};
|
||||
handler.post(runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
shouldstop = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ public class CodeOverlayView extends View {
|
||||
}
|
||||
}
|
||||
if(barColors != null){
|
||||
final double width = getWidth()/barColors.length;
|
||||
final double width = (double) getWidth() /barColors.length;
|
||||
|
||||
final int top = 0;
|
||||
final int bottom = barHeight;
|
||||
|
||||
@@ -14,19 +14,69 @@ import com.google.zxing.Reader;
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.common.HybridBinarizer;
|
||||
import com.google.zxing.datamatrix.DataMatrixReader;
|
||||
import com.ridgebotics.ridgescout.utility.TaskRunner;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.function.Function;
|
||||
|
||||
// Background task for code scanning, to not slow down the scanner.
|
||||
public class CodeScanTask extends AsyncTask<String, String, String>{
|
||||
private Function<String, String> resultFunction = null;
|
||||
//public class CodeScanTask extends AsyncTask<String, String, String>{
|
||||
// private Function<String, String> resultFunction = null;
|
||||
// private Bitmap image;
|
||||
//
|
||||
// @Override
|
||||
// protected String doInBackground(String... str) {
|
||||
// if(image == null){return null;}
|
||||
//
|
||||
// int width = image.getWidth();
|
||||
// int height = image.getHeight();
|
||||
// int[] pixels = new int[width * height];
|
||||
// image.getPixels(pixels, 0, width, 0, 0, width, height);
|
||||
//
|
||||
// RGBLuminanceSource source = new RGBLuminanceSource(width, height, pixels);
|
||||
// BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));
|
||||
//
|
||||
// Map<DecodeHintType, Object> hints = new HashMap<>();
|
||||
// hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
|
||||
//// hints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);
|
||||
// hints.put(DecodeHintType.POSSIBLE_FORMATS, EnumSet.of(BarcodeFormat.DATA_MATRIX));
|
||||
//
|
||||
// Reader reader = new DataMatrixReader();
|
||||
// try {
|
||||
// Result result = reader.decode(binaryBitmap, hints);
|
||||
// return result.getText();
|
||||
// } catch (NotFoundException | ChecksumException | FormatException e) {
|
||||
//// AlertManager.error(e);
|
||||
// }
|
||||
//
|
||||
// return null;
|
||||
// }
|
||||
// public void setImage(Bitmap image){this.image = image;}
|
||||
// public void onResult(Function<String, String> func) {
|
||||
// this.resultFunction = func;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected void onPostExecute(String result) {
|
||||
// super.onPostExecute(result);
|
||||
// if(resultFunction != null){
|
||||
// resultFunction.apply(result);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
public class CodeScanTask implements Callable<String> {
|
||||
private Bitmap image;
|
||||
|
||||
public CodeScanTask(Bitmap image) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doInBackground(String... str) {
|
||||
public String call() {
|
||||
if(image == null){return null;}
|
||||
|
||||
int width = image.getWidth();
|
||||
@@ -52,17 +102,4 @@ public class CodeScanTask extends AsyncTask<String, String, String>{
|
||||
|
||||
return null;
|
||||
}
|
||||
public void setImage(Bitmap image){this.image = image;}
|
||||
public void onResult(Function<String, String> func) {
|
||||
this.resultFunction = func;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String result) {
|
||||
super.onPostExecute(result);
|
||||
if(resultFunction != null){
|
||||
resultFunction.apply(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+44
-37
@@ -6,6 +6,7 @@ import android.Manifest;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Matrix;
|
||||
import android.media.Image;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
@@ -38,11 +39,15 @@ import com.ridgebotics.ridgescout.utility.AlertManager;
|
||||
import com.ridgebotics.ridgescout.utility.BuiltByteParser;
|
||||
import com.ridgebotics.ridgescout.utility.FileEditor;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.ridgebotics.ridgescout.utility.TaskRunner;
|
||||
|
||||
import org.checkerframework.checker.units.qual.C;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
@@ -62,21 +67,12 @@ public class CodeScannerView extends Fragment {
|
||||
alert.create().show();
|
||||
}
|
||||
|
||||
|
||||
private float scale = 0;
|
||||
private final int downscale = 1;
|
||||
private LifecycleOwner lifecycle;
|
||||
|
||||
private void setImage(Bitmap bmp){
|
||||
if(scale == 0) {
|
||||
scale = ((float) binding.container.getWidth() / bmp.getWidth()) * ((float) 16 / 9);
|
||||
binding.scannerImage.setTranslationX(0);
|
||||
binding.scannerImage.setTranslationY(0);
|
||||
}
|
||||
scanQRCode(bmp);
|
||||
binding.scannerImage.setImageBitmap(bmp);
|
||||
binding.scannerThreshold.bringToFront();
|
||||
// alert("test", getChildCount()+"");
|
||||
}
|
||||
|
||||
// private Bitmap img
|
||||
@@ -99,37 +95,38 @@ public class CodeScannerView extends Fragment {
|
||||
final int height = image.getHeight();
|
||||
|
||||
int[] pixels = new int[width * height];
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
int L = levelMap[yBuffer.get() & 0xff];
|
||||
pixels[y * width + x] = 0xff000000 | (L << 16) | (L << 8) | L;
|
||||
}
|
||||
for (int i = 0; i < width*height; i++) {
|
||||
int L = levelMap[yBuffer.get(i) & 0xff];
|
||||
pixels[i] = 0xff000000 | (L << 16) | (L << 8) | L;
|
||||
}
|
||||
|
||||
Matrix matrix = new Matrix();
|
||||
|
||||
matrix.postRotate(90);
|
||||
|
||||
|
||||
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
|
||||
bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
|
||||
// Bitmap.rota
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
public void scanQRCode(Bitmap bitmap) {
|
||||
|
||||
CodeScanTask async = new CodeScanTask();
|
||||
async.setImage(bitmap);
|
||||
async.onResult(data -> {
|
||||
// CodeScanTask async = new CodeScanTask();
|
||||
new TaskRunner().executeAsync(new CodeScanTask(bitmap), data -> {
|
||||
if(data != null){
|
||||
// alert("test", ""+fileEditor.byteFromChar(data.charAt(0)));
|
||||
compileData(
|
||||
FileEditor.byteFromChar(data.charAt(0)),
|
||||
FileEditor.byteFromChar(data.charAt(1)),
|
||||
FileEditor.byteFromChar(data.charAt(2)),
|
||||
(FileEditor.byteFromChar(data.charAt(3))+1),
|
||||
data.substring(4)
|
||||
FileEditor.byteFromChar(data.charAt(0)),
|
||||
FileEditor.byteFromChar(data.charAt(1)),
|
||||
FileEditor.byteFromChar(data.charAt(2)),
|
||||
(FileEditor.byteFromChar(data.charAt(3))+1),
|
||||
data.substring(4)
|
||||
);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
async.execute();
|
||||
|
||||
|
||||
|
||||
// return contents;
|
||||
@@ -231,26 +228,23 @@ public class CodeScannerView extends Fragment {
|
||||
|
||||
void bindPreview(@NonNull ProcessCameraProvider cameraProvider) {
|
||||
|
||||
Preview preview = new Preview.Builder()
|
||||
.setTargetAspectRatio(AspectRatio.RATIO_16_9)
|
||||
.setTargetRotation(Surface.ROTATION_180)
|
||||
.build();
|
||||
Preview preview = new Preview.Builder().build();
|
||||
|
||||
CameraSelector cameraSelector = new CameraSelector.Builder()
|
||||
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
|
||||
|
||||
// .addCameraFilter(CameraFilters.NON)
|
||||
.build();
|
||||
|
||||
ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
|
||||
ImageAnalysis imageAnalysis = new ImageAnalysis.Builder()
|
||||
// .setTargetResolution(new Size(224, 224))
|
||||
.setOutputImageRotationEnabled(false)
|
||||
.setTargetAspectRatio(AspectRatio.RATIO_16_9)
|
||||
// .setTargetAspectRatio(AspectRatio.RATIO_16_9)
|
||||
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
|
||||
// .setOutputImageRotationEnabled(true)
|
||||
// .setTargetRotation(Surface.ROTATION_0)
|
||||
.build();
|
||||
|
||||
|
||||
imageAnalysis.setAnalyzer(executor, new ImageAnalysis.Analyzer() {
|
||||
@OptIn(markerClass = ExperimentalGetImage.class) @Override
|
||||
public void analyze(@NonNull ImageProxy image) {
|
||||
@@ -269,6 +263,7 @@ public class CodeScannerView extends Fragment {
|
||||
});
|
||||
|
||||
cameraProvider.unbindAll();
|
||||
// cameraProvider.ro
|
||||
|
||||
cameraProvider.bindToLifecycle(lifecycle,
|
||||
cameraSelector, imageAnalysis, preview);
|
||||
@@ -295,6 +290,7 @@ public class CodeScannerView extends Fragment {
|
||||
Log.i("title", ""+qrCount);
|
||||
barColors = new int[qrCount];
|
||||
prevQrIndex = qrIndex;
|
||||
qrScannedCount = 0;
|
||||
}
|
||||
|
||||
final boolean updated;
|
||||
@@ -313,8 +309,20 @@ public class CodeScannerView extends Fragment {
|
||||
|
||||
if(updated && qrScannedCount >= qrCount){
|
||||
|
||||
AlertManager.startLoading("Decoding data...");
|
||||
new TaskRunner().executeAsync(new CodeDecodeTask(), result -> {
|
||||
AlertManager.stopLoading();
|
||||
});
|
||||
|
||||
}
|
||||
prevQrIndex = qrIndex;
|
||||
}
|
||||
|
||||
private class CodeDecodeTask implements Callable<Void> {
|
||||
@Override
|
||||
public Void call() {
|
||||
String compiledString = "";
|
||||
for(int i=0;i<qrCount;i++){
|
||||
for(int i=0;i<qrDataArr.length;i++){
|
||||
compiledString += qrDataArr[i];
|
||||
}
|
||||
|
||||
@@ -342,9 +350,8 @@ public class CodeScannerView extends Fragment {
|
||||
}catch (Exception e){
|
||||
AlertManager.error(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
prevQrIndex = qrIndex;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ public class CustomSpinnerView extends LinearLayout {
|
||||
this.index = defaultOption;
|
||||
|
||||
if(defaultOption != -1)
|
||||
this.item.setText(options.get(defaultOption));
|
||||
this.item.setText("▼ " + options.get(defaultOption));
|
||||
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||
@@ -78,7 +78,7 @@ public class CustomSpinnerView extends LinearLayout {
|
||||
CustomSpinnerPopup popup = new CustomSpinnerPopup(getContext()).init(options, option -> {
|
||||
// dialog.();
|
||||
if(!isEnabled()) return;
|
||||
item.setText(option);
|
||||
item.setText("▼ " + option);
|
||||
index = options.indexOf(option);
|
||||
if(onClickListener != null) {
|
||||
onClickListener.onClick(option, options.indexOf(option));
|
||||
@@ -105,12 +105,12 @@ public class CustomSpinnerView extends LinearLayout {
|
||||
}
|
||||
|
||||
public void setOption(String option) {
|
||||
item.setText(option);
|
||||
item.setText("▼ " + option);
|
||||
index = options.indexOf(option);
|
||||
}
|
||||
|
||||
public void setOption(int index) {
|
||||
item.setText(options.get(index));
|
||||
item.setText("▼ " + options.get(index));
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.ridgebotics.ridgescout.ui.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
@@ -54,6 +55,20 @@ public class MatchScoutingIndicator extends RelativeLayout {
|
||||
match_indicator_bar_team_num = findViewById(R.id.match_indicator_bar_team_num);
|
||||
box = findViewById(R.id.file_indicator_box);
|
||||
coloredBackground = findViewById(R.id.match_indicator_background);
|
||||
|
||||
int currentNightMode = getContext().getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
|
||||
switch (currentNightMode) {
|
||||
case Configuration.UI_MODE_NIGHT_NO:
|
||||
// Night mode is not active on device
|
||||
match_indicator_back_button.setColorFilter(Color.BLACK, PorterDuff.Mode.SRC_IN);
|
||||
match_indicator_next_button.setColorFilter(Color.BLACK, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case Configuration.UI_MODE_NIGHT_YES:
|
||||
// Night mode is active on device
|
||||
match_indicator_back_button.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN);
|
||||
match_indicator_next_button.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void setUsername(String username){
|
||||
@@ -73,19 +88,31 @@ public class MatchScoutingIndicator extends RelativeLayout {
|
||||
}
|
||||
|
||||
public void setColor(int color){
|
||||
Drawable drawable = box.getBackground();
|
||||
drawable.mutate();
|
||||
drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
|
||||
// Set color of main background rectangle
|
||||
Drawable box_drawable = box.getBackground();
|
||||
box_drawable.mutate();
|
||||
box_drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
|
||||
|
||||
float[] hsv = new float[3];
|
||||
Color.colorToHSV(color,hsv);
|
||||
|
||||
int background_color = Color.HSVToColor(220, new float[]{
|
||||
hsv[0],
|
||||
Math.min(hsv[1], 0.75f),
|
||||
Math.min(hsv[2], 0.5f)
|
||||
});
|
||||
|
||||
// Set color of main background rectangle, slightly dimmer
|
||||
coloredBackground.setBackgroundColor(
|
||||
Color.HSVToColor(220, new float[]{
|
||||
hsv[0],
|
||||
Math.min(hsv[1], 0.75f),
|
||||
Math.min(hsv[2], 0.5f)
|
||||
})
|
||||
background_color
|
||||
);
|
||||
|
||||
Drawable left_drawable = match_indicator_back_button.getBackground();
|
||||
left_drawable.mutate();
|
||||
left_drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
|
||||
|
||||
Drawable right_drawable = match_indicator_next_button.getBackground();
|
||||
right_drawable.mutate();
|
||||
right_drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.ridgebotics.ridgescout.ui.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
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.ImageButton;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
|
||||
import com.ridgebotics.ridgescout.R;
|
||||
|
||||
// A view for displaying information about a team.
|
||||
public class PitScoutingIndicator extends RelativeLayout {
|
||||
public PitScoutingIndicator(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context);
|
||||
}
|
||||
|
||||
public PitScoutingIndicator(Context context) {
|
||||
super(context);
|
||||
init(context);
|
||||
}
|
||||
|
||||
public TextView pit_indicator_username;
|
||||
public TextView pit_indicator_team_num;
|
||||
private ConstraintLayout box;
|
||||
private View coloredBackground;
|
||||
|
||||
public void init(Context context) {
|
||||
LayoutInflater.from(context).inflate(R.layout.view_pit_scouting_indicator, this, true);
|
||||
pit_indicator_username = findViewById(R.id.pit_indicator_username);
|
||||
pit_indicator_team_num = findViewById(R.id.pit_indicator_teamnum);
|
||||
|
||||
box = findViewById(R.id.pit_indicator_box);
|
||||
coloredBackground = findViewById(R.id.pit_indicator_background);
|
||||
|
||||
}
|
||||
|
||||
public void setUsername(String username){
|
||||
pit_indicator_username.setText(username);
|
||||
}
|
||||
|
||||
public void setTeamNum(int teamNum) {
|
||||
pit_indicator_team_num.setText(String.valueOf(teamNum));
|
||||
}
|
||||
|
||||
public void setColor(int color){
|
||||
// Set color of main background rectangle
|
||||
Drawable box_drawable = box.getBackground();
|
||||
box_drawable.mutate();
|
||||
box_drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
|
||||
|
||||
float[] hsv = new float[3];
|
||||
Color.colorToHSV(color,hsv);
|
||||
|
||||
int background_color = Color.HSVToColor(220, new float[]{
|
||||
hsv[0],
|
||||
Math.min(hsv[1], 0.75f),
|
||||
Math.min(hsv[2], 0.5f)
|
||||
});
|
||||
|
||||
// Set color of main background rectangle, slightly dimmer
|
||||
coloredBackground.setBackgroundColor(
|
||||
background_color
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.ridgebotics.ridgescout.ui.views;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class RecyclerAdapter<T> extends RecyclerView.Adapter<RecyclerHolder<T>> {
|
||||
private List<T> items;
|
||||
private final int layoutResId;
|
||||
private final RecyclerHolderFactory<T> viewHolderFactory;
|
||||
private RecyclerClickListener<T> onItemClickListener;
|
||||
|
||||
public RecyclerAdapter(int layoutResId, RecyclerHolderFactory<T> viewHolderFactory) {
|
||||
this.items = new ArrayList<>();
|
||||
this.layoutResId = layoutResId;
|
||||
this.viewHolderFactory = viewHolderFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecyclerHolder<T> onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(layoutResId, parent, false);
|
||||
return viewHolderFactory.createViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(RecyclerHolder<T> holder, int position) {
|
||||
T item = items.get(position);
|
||||
holder.bind(item, position);
|
||||
holder.setOnItemClickListener(item, onItemClickListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return items.size();
|
||||
}
|
||||
|
||||
// List management methods
|
||||
public void setItems(List<T> newItems) {
|
||||
this.items.clear();
|
||||
if (newItems != null) {
|
||||
this.items.addAll(newItems);
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void addItem(T item) {
|
||||
items.add(item);
|
||||
notifyItemInserted(items.size() - 1);
|
||||
}
|
||||
|
||||
public void addItem(int position, T item) {
|
||||
items.add(position, item);
|
||||
notifyItemInserted(position);
|
||||
}
|
||||
|
||||
public void removeItem(int position) {
|
||||
if (position >= 0 && position < items.size()) {
|
||||
items.remove(position);
|
||||
notifyItemRemoved(position);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeItem(T item) {
|
||||
int position = items.indexOf(item);
|
||||
if (position != -1) {
|
||||
removeItem(position);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateItem(int position, T item) {
|
||||
if (position >= 0 && position < items.size()) {
|
||||
items.set(position, item);
|
||||
notifyItemChanged(position);
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
int size = items.size();
|
||||
items.clear();
|
||||
notifyItemRangeRemoved(0, size);
|
||||
}
|
||||
|
||||
public T getItem(int position) {
|
||||
return items.get(position);
|
||||
}
|
||||
|
||||
public List<T> getItems() {
|
||||
return new ArrayList<>(items);
|
||||
}
|
||||
|
||||
public void setOnItemClickListener(RecyclerClickListener<T> listener) {
|
||||
this.onItemClickListener = listener;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.ridgebotics.ridgescout.ui.views;
|
||||
|
||||
public interface RecyclerClickListener<T> {
|
||||
void onItemClick(T item, int position);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.ridgebotics.ridgescout.ui.views;
|
||||
|
||||
import android.view.View;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public abstract class RecyclerHolder<T> extends RecyclerView.ViewHolder {
|
||||
public RecyclerHolder(View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
public abstract void bind(T item, int position);
|
||||
|
||||
// Optional method for handling item clicks
|
||||
public void setOnItemClickListener(T item, RecyclerClickListener<T> listener) {
|
||||
if (listener != null) {
|
||||
itemView.setOnClickListener(v -> listener.onItemClick(item, getAdapterPosition()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.ridgebotics.ridgescout.ui.views;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
public interface RecyclerHolderFactory<T> {
|
||||
RecyclerHolder<T> createViewHolder(View itemView);
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
package com.ridgebotics.ridgescout.ui.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import java.util.List;
|
||||
|
||||
public class RecyclerList<T> extends RecyclerView {
|
||||
private RecyclerAdapter<T> adapter;
|
||||
|
||||
public RecyclerList(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public RecyclerList(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public RecyclerList(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
// Set default layout manager
|
||||
setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
|
||||
// Enable optimizations
|
||||
setHasFixedSize(true);
|
||||
setItemViewCacheSize(20);
|
||||
setDrawingCacheEnabled(true);
|
||||
setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
|
||||
}
|
||||
|
||||
// Setup method to configure the RecyclerView
|
||||
public RecyclerList<T> setup(int layoutResId, RecyclerHolderFactory<T> RecyclerHolderFactory) {
|
||||
adapter = new RecyclerAdapter<>(layoutResId, RecyclerHolderFactory);
|
||||
setAdapter(adapter);
|
||||
return this;
|
||||
}
|
||||
|
||||
// Layout manager convenience methods
|
||||
public RecyclerList<T> withLinearLayout() {
|
||||
setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
return this;
|
||||
}
|
||||
|
||||
public RecyclerList<T> withLinearLayout(int orientation) {
|
||||
setLayoutManager(new LinearLayoutManager(getContext(), orientation, false));
|
||||
return this;
|
||||
}
|
||||
|
||||
public RecyclerList<T> withGridLayout(int spanCount) {
|
||||
setLayoutManager(new GridLayoutManager(getContext(), spanCount));
|
||||
return this;
|
||||
}
|
||||
|
||||
public RecyclerList<T> withDivider() {
|
||||
DividerItemDecoration divider = new DividerItemDecoration(getContext(),
|
||||
DividerItemDecoration.VERTICAL);
|
||||
addItemDecoration(divider);
|
||||
return this;
|
||||
}
|
||||
|
||||
public RecyclerList<T> withItemClickListener(RecyclerClickListener<T> listener) {
|
||||
if (adapter != null) {
|
||||
adapter.setOnItemClickListener(listener);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
// Data management methods
|
||||
public void setItems(List<T> items) {
|
||||
if (adapter != null) {
|
||||
adapter.setItems(items);
|
||||
}
|
||||
}
|
||||
|
||||
public void addItem(T item) {
|
||||
if (adapter != null) {
|
||||
adapter.addItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
public void addItem(int position, T item) {
|
||||
if (adapter != null) {
|
||||
adapter.addItem(position, item);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeItem(int position) {
|
||||
if (adapter != null) {
|
||||
adapter.removeItem(position);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeItem(T item) {
|
||||
if (adapter != null) {
|
||||
adapter.removeItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateItem(int position, T item) {
|
||||
if (adapter != null) {
|
||||
adapter.updateItem(position, item);
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
if (adapter != null) {
|
||||
adapter.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public T getItem(int position) {
|
||||
return adapter != null ? adapter.getItem(position) : null;
|
||||
}
|
||||
|
||||
public List<T> getItems() {
|
||||
return adapter != null ? adapter.getItems() : null;
|
||||
}
|
||||
|
||||
public RecyclerAdapter<T> getGenericAdapter() {
|
||||
return adapter;
|
||||
}
|
||||
}
|
||||
@@ -19,34 +19,37 @@ import com.ridgebotics.ridgescout.R;
|
||||
import com.ridgebotics.ridgescout.types.frcTeam;
|
||||
|
||||
// A view that acts as a row specifically to display a team and their icon in a list formmt.
|
||||
public class TeamListOption extends LinearLayout {
|
||||
public TeamListOption(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context);
|
||||
}
|
||||
public class TeamListOption extends RecyclerHolder<frcTeam> {
|
||||
|
||||
public TeamListOption(Context context) {
|
||||
super(context);
|
||||
init(context);
|
||||
}
|
||||
|
||||
// public TeamListOption(Context context, @Nullable AttributeSet attrs) {
|
||||
// super(context, attrs);
|
||||
// init(context);
|
||||
// }
|
||||
//
|
||||
// public TeamListOption(Context context) {
|
||||
// super(context);
|
||||
// init(context);
|
||||
// }
|
||||
//
|
||||
private TextView teamNumber;
|
||||
private TextView teamName;
|
||||
|
||||
private ImageView teamLogo;
|
||||
private ConstraintLayout box;
|
||||
private View coloredBackground;
|
||||
//
|
||||
public TeamListOption(View view) {
|
||||
super(view);
|
||||
// LayoutInflater.from(context).inflate(R.layout.view_team_option, this, true);
|
||||
|
||||
public void init(Context context) {
|
||||
LayoutInflater.from(context).inflate(R.layout.view_team_option, this, true);
|
||||
|
||||
teamNumber = findViewById(R.id.field_option_type);
|
||||
teamName = findViewById(R.id.field_option_name);
|
||||
teamLogo = findViewById(R.id.team_option_logo);
|
||||
teamNumber = view.findViewById(R.id.field_option_type);
|
||||
teamName = view.findViewById(R.id.field_option_name);
|
||||
teamLogo = view.findViewById(R.id.team_option_logo);
|
||||
|
||||
|
||||
box = findViewById(R.id.team_option_box);
|
||||
coloredBackground = findViewById(R.id.team_option_background);
|
||||
box = view.findViewById(R.id.team_option_box);
|
||||
coloredBackground = view.findViewById(R.id.team_option_background);
|
||||
}
|
||||
|
||||
public void setTeamNumber(int num){
|
||||
@@ -59,6 +62,7 @@ public class TeamListOption extends LinearLayout {
|
||||
|
||||
public void setTeamLogo(Bitmap bitmap){
|
||||
teamLogo.setImageBitmap(bitmap);
|
||||
showLogo();
|
||||
}
|
||||
|
||||
public void hideLogo(){
|
||||
@@ -68,7 +72,8 @@ public class TeamListOption extends LinearLayout {
|
||||
teamLogo.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
public void fromTeam(frcTeam team){
|
||||
@Override
|
||||
public void bind(frcTeam team, int position){
|
||||
setTeamNumber(team.teamNumber);
|
||||
setTeamName(team.teamName);
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.ridgebotics.ridgescout.utility;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.widget.Toast;
|
||||
@@ -113,4 +114,22 @@ public class AlertManager {
|
||||
});
|
||||
}
|
||||
|
||||
private static ProgressDialog loadingDialog;
|
||||
|
||||
public static void startLoading(String title){
|
||||
((Activity) context).runOnUiThread(() -> {
|
||||
if(loadingDialog != null && loadingDialog.isShowing())
|
||||
loadingDialog.dismiss();
|
||||
loadingDialog = ProgressDialog.show(context, title, "Please wait...");
|
||||
});
|
||||
}
|
||||
|
||||
public static void stopLoading(){
|
||||
((Activity) context).runOnUiThread(() -> {
|
||||
if (loadingDialog != null)
|
||||
loadingDialog.cancel();
|
||||
loadingDialog = null;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import android.graphics.Color;
|
||||
public class Colors {
|
||||
// Lists and stuff
|
||||
public static final int color_found = 0x7f00ff00;
|
||||
public static final int color_rescout = 0x7f0000ff;
|
||||
public static final int color_rescout = 0xff007fff;
|
||||
public static final int color_not_found = 0x7f7f0000;
|
||||
|
||||
|
||||
@@ -14,9 +14,9 @@ public class Colors {
|
||||
public static final int unfocused_background_color = 0x50118811;
|
||||
|
||||
|
||||
public static final int unsaved_color = 0x60ff0000;
|
||||
public static final int saved_color = 0x6000ff00;
|
||||
public static final int rescout_color = 0x600000ff;
|
||||
public static final int unsaved_color = 0xffaa0000;
|
||||
public static final int saved_color = 0xff00aa00;
|
||||
public static final int rescout_color = 0xff007fff;
|
||||
|
||||
|
||||
// Data graphs
|
||||
|
||||
@@ -100,7 +100,7 @@ public final class FileEditor {
|
||||
|
||||
|
||||
public static int byteFromChar(char c){
|
||||
byte[] bytes = (String.valueOf(c)).getBytes(Charset.defaultCharset());
|
||||
byte[] bytes = (String.valueOf(c)).getBytes(StandardCharsets.ISO_8859_1);
|
||||
return Byte.toUnsignedInt(bytes[0]);
|
||||
}
|
||||
|
||||
@@ -398,9 +398,10 @@ public final class FileEditor {
|
||||
Arrays.sort(filenames, (o1, o2) -> {
|
||||
try {
|
||||
if (!o1.contains("-") || !o2.contains("-"))
|
||||
return 0;
|
||||
return Integer.valueOf(o1.split("-")[1]).compareTo(Integer.valueOf(o2.split("-")[1]));
|
||||
return o2.compareTo(o1);
|
||||
return Integer.valueOf(o1.split("-")[1].split("\\.")[0]).compareTo(Integer.valueOf(o2.split("-")[1].split("\\.")[0]));
|
||||
} catch (Exception e) {
|
||||
AlertManager.error(e);
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -25,11 +25,24 @@ public class ImageRequestTask extends AsyncTask<String, Void, Bitmap> {
|
||||
try {
|
||||
URL url = new URL(src);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
// We do a little bit of spoofing
|
||||
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11");
|
||||
connection.setDoInput(true);
|
||||
connection.connect();
|
||||
InputStream input = connection.getInputStream();
|
||||
return BitmapFactory.decodeStream(input);
|
||||
} catch (FileNotFoundException e) {
|
||||
|
||||
int code = connection.getResponseCode();
|
||||
switch (code) {
|
||||
case 200:
|
||||
InputStream input = connection.getInputStream();
|
||||
return BitmapFactory.decodeStream(input);
|
||||
case 403:
|
||||
// AlertManager.error("Got 403, Going to https://www.thebluealliance.com/avatars may fix this");
|
||||
return null;
|
||||
default:
|
||||
AlertManager.error("Error downloading image " + src, "Got response code: " + code);
|
||||
return null;
|
||||
}
|
||||
} catch (FileNotFoundException e){
|
||||
return null;
|
||||
} catch (IOException e){
|
||||
AlertManager.error("Error downloading image " + src, e);
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.ridgebotics.ridgescout.utility;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
// https://stackoverflow.com/questions/58767733/the-asynctask-api-is-deprecated-in-android-11-what-are-the-alternatives
|
||||
public class TaskRunner {
|
||||
private final Executor executor = Executors.newSingleThreadExecutor(); // change according to your requirements
|
||||
private final Handler handler = new Handler(Looper.getMainLooper());
|
||||
|
||||
public interface Callback<R> {
|
||||
void onComplete(R result);
|
||||
}
|
||||
|
||||
public <R> void executeAsync(Callable<R> callable, Callback<R> callback) {
|
||||
executor.execute(() -> {
|
||||
final R result;
|
||||
try {
|
||||
result = callable.call();
|
||||
handler.post(() -> {
|
||||
callback.onComplete(result);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -17,36 +17,23 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ScrollView
|
||||
<LinearLayout
|
||||
android:id="@+id/table"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="50dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TableLayout
|
||||
android:id="@+id/table"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.ridgebotics.ridgescout.ui.views.CustomSpinnerView
|
||||
android:id="@+id/data_type_dropdown"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</TableLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
<com.ridgebotics.ridgescout.ui.views.CustomSpinnerView
|
||||
android:id="@+id/data_type_dropdown"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -92,17 +92,6 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_next_match"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:text="TextView"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/text_name" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_match_alliance"
|
||||
android:layout_width="wrap_content"
|
||||
@@ -122,6 +111,15 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/event_button" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/info_box"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/text_name" />
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:text="Scouting Notice"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1"></TextView>
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
||||
@@ -4,54 +4,27 @@
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/pit_file_indicator"
|
||||
<com.ridgebotics.ridgescout.ui.views.PitScoutingIndicator
|
||||
android:id="@+id/pit_indicator"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="#60ff0000"
|
||||
android:layout_height="60dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pit_bar_team_num"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="4388"
|
||||
android:textAlignment="center"
|
||||
android:textSize="24sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pitUsername"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Username"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/pit_bar_team_num"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
||||
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/pitScoutArea"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="48dp">
|
||||
android:paddingTop="60dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/scouting_notice_box"
|
||||
@@ -60,16 +33,15 @@
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_margin="5dp"
|
||||
android:background="@drawable/border"
|
||||
android:padding="10dp"
|
||||
android:orientation="horizontal">
|
||||
android:orientation="horizontal"
|
||||
android:padding="10dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/scouting_notice_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1"
|
||||
android:text="Scouting Notice">
|
||||
</TextView>
|
||||
android:text="Scouting Notice"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1"></TextView>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
android:id="@+id/scrollView2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="60dp"
|
||||
android:fillViewport="true"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
@@ -18,55 +17,70 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TableLayout
|
||||
android:id="@+id/SettingsTable"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
</TableLayout>
|
||||
<TableLayout
|
||||
android:id="@+id/SettingsTable"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" />
|
||||
|
||||
|
||||
<!-- <Button-->
|
||||
<!-- android:id="@+id/scoutNoticeButton"-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:layout_weight="1"-->
|
||||
<!-- android:layout_margin="5dp"-->
|
||||
<!-- android:text="Edit Scout notice"-->
|
||||
<!-- android:textSize="16sp" />-->
|
||||
|
||||
<!-- <LinearLayout-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:orientation="horizontal">-->
|
||||
|
||||
<!-- <Button-->
|
||||
<!-- android:id="@+id/fieldsPitsButton"-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:layout_weight="1"-->
|
||||
<!-- android:layout_margin="5dp"-->
|
||||
<!-- android:text="Edit PIT Fields"-->
|
||||
<!-- android:textSize="16sp" />-->
|
||||
|
||||
<!-- <Button-->
|
||||
<!-- android:id="@+id/fieldsMatchesButton"-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:layout_weight="1"-->
|
||||
<!-- android:layout_margin="5dp"-->
|
||||
<!-- android:text="Edit MATCH Fields"-->
|
||||
<!-- android:textSize="16sp" />-->
|
||||
|
||||
<!-- </LinearLayout>-->
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
|
||||
<Button
|
||||
android:id="@+id/fieldsButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Fields"
|
||||
android:textSize="34sp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/scrollView2"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
<!-- <LinearLayout-->
|
||||
<!-- android:id="@+id/fieldsButtons"-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:layout_marginTop="1dp"-->
|
||||
<!-- android:gravity="center"-->
|
||||
<!-- android:orientation="horizontal"-->
|
||||
<!-- android:visibility="gone"-->
|
||||
<!-- app:layout_constraintEnd_toEndOf="parent"-->
|
||||
<!-- app:layout_constraintStart_toStartOf="parent"-->
|
||||
<!-- app:layout_constraintBottom_toTopOf="@+id/fieldsButton"-->
|
||||
<!-- tools:visibility="visible">-->
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/fieldsButtons"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="1dp"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@+id/fieldsButton"
|
||||
tools:visibility="visible">
|
||||
|
||||
<Button
|
||||
android:id="@+id/fieldsPitsButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="5dp"
|
||||
android:text="Pits"
|
||||
android:textSize="34sp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/fieldsMatchesButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="5dp"
|
||||
android:text="Matches"
|
||||
android:textSize="34sp" />
|
||||
</LinearLayout>
|
||||
<!-- </LinearLayout>-->
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -14,8 +14,7 @@
|
||||
android:id="@+id/teams"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="48dp" />
|
||||
android:orientation="vertical" />
|
||||
</ScrollView>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -7,77 +7,65 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/scannerColors"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginTop="15dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/scannerThreshold"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/scannerColors" />
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/scannerBrightness"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/scannerThreshold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/scannerColorsLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginBottom="-12dp"
|
||||
android:text="Posterize"
|
||||
app:layout_constraintBottom_toTopOf="@+id/scannerColors"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/scannerThresholdLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginBottom="-12dp"
|
||||
android:text="Exposure"
|
||||
app:layout_constraintBottom_toTopOf="@+id/scannerThreshold"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/scannerBrightnessLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginBottom="-12dp"
|
||||
android:text="Brightness"
|
||||
app:layout_constraintBottom_toTopOf="@+id/scannerBrightness"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/scannerImage"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:adjustViewBounds="true"
|
||||
android:rotation="90"
|
||||
android:scaleType="fitCenter"
|
||||
android:scaleX="1"
|
||||
android:scaleY="1"
|
||||
android:translationY="-40dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:context=".CodeScannerView" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="3dp"
|
||||
android:padding="3dp"
|
||||
android:background="@drawable/border"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
tools:layout_editor_absoluteX="3dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/scannerColorsLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Posterize"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"/>
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/scannerColors"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginTop="15dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/scannerThresholdLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Exposure"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"/>
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/scannerThreshold"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/scannerBrightnessLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Brightness"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"/>
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/scannerBrightness"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -1,31 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/qrSizeSlider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginBottom="60dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/qrImage" />
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/qrSpeedSlider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginBottom="60dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/qrSizeSlider"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.971"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/qrImage"
|
||||
app:layout_constraintVertical_bias="0.93" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/qrImage"
|
||||
android:layout_width="match_parent"
|
||||
@@ -36,23 +15,48 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/qrSpeedText"
|
||||
android:layout_width="wrap_content"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:text="QR Speed"
|
||||
app:layout_constraintBottom_toTopOf="@+id/qrSpeedSlider"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
android:layout_margin="3dp"
|
||||
android:orientation="vertical"
|
||||
android:background="@drawable/border"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/qrSizeText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:text="QR Size"
|
||||
app:layout_constraintBottom_toTopOf="@+id/qrSizeSlider"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/qrSpeedText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:text="QR Speed"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
||||
app:layout_constraintBottom_toTopOf="@+id/qrSpeedSlider" />
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/qrSpeedSlider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/qrSizeText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:text="QR Size"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6" />
|
||||
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/qrSizeSlider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
tools:layout_editor_absoluteY="135dp" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/qrIndexN"
|
||||
@@ -60,7 +64,8 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:text="0"
|
||||
app:layout_constraintEnd_toStartOf="@+id/qrIndexSlash"
|
||||
app:layout_constraintTop_toBottomOf="@+id/qrImage" />
|
||||
app:layout_constraintTop_toBottomOf="@+id/qrImage"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/qrIndexSlash"
|
||||
@@ -69,7 +74,8 @@
|
||||
android:text="/"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/qrImage" />
|
||||
app:layout_constraintTop_toBottomOf="@+id/qrImage"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/qrIndexD"
|
||||
@@ -77,6 +83,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:text="0"
|
||||
app:layout_constraintStart_toEndOf="@+id/qrIndexSlash"
|
||||
app:layout_constraintTop_toBottomOf="@+id/qrImage" />
|
||||
app:layout_constraintTop_toBottomOf="@+id/qrImage"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -8,9 +8,12 @@
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="3dp"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginLeft="3dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginRight="3dp"
|
||||
android:layout_marginBottom="3dp"
|
||||
android:background="@drawable/border"
|
||||
android:orientation="horizontal"
|
||||
tools:ignore="UselessParent">
|
||||
|
||||
<TextView
|
||||
@@ -18,8 +21,9 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="10dp"
|
||||
android:textSize="24sp"
|
||||
android:overlapAnchor="false"/>
|
||||
android:overlapAnchor="false"
|
||||
android:text="▼ Options"
|
||||
android:textSize="24sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -28,9 +32,9 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="9dp"
|
||||
android:layout_marginTop="-5dp"
|
||||
android:layout_marginTop="-6dp"
|
||||
android:paddingLeft="3dp"
|
||||
android:paddingRight="3dp"
|
||||
android:text="Test"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1"/>
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1" />
|
||||
</RelativeLayout>
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="5dp"
|
||||
android:background="@drawable/border"
|
||||
android:padding="3dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
@@ -23,16 +22,18 @@
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="gone" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/match_indicator_back_button"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:contentDescription="Back"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/triangle_left"
|
||||
android:text="Back"
|
||||
android:background="@color/zxing_transparent"
|
||||
android:background="@drawable/border"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
@@ -42,9 +43,10 @@
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:contentDescription="Next"
|
||||
android:src="@drawable/triangle_right"
|
||||
android:text="Next"
|
||||
android:background="@color/zxing_transparent"
|
||||
android:background="@drawable/border"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
@@ -53,24 +55,24 @@
|
||||
android:id="@+id/match_indicator_alliance_pos_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:layout_marginEnd="58dp"
|
||||
android:text="Temp"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1"
|
||||
android:textAlignment="center"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/match_indicator_next_button"
|
||||
app:layout_constraintEnd_toEndOf="@+id/match_indicator_next_button"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/match_indicator_username"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginStart="58dp"
|
||||
android:text="Temp"
|
||||
android:textAlignment="center"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/match_indicator_back_button"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout 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">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/pit_indicator_box"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="5dp"
|
||||
android:background="@drawable/border"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<View
|
||||
android:id="@+id/pit_indicator_background"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pit_indicator_username"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="58dp"
|
||||
android:text="Username"
|
||||
android:textAlignment="center"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pit_indicator_teamnum"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:text="4388"
|
||||
android:textAlignment="center"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline5"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</RelativeLayout>
|
||||
@@ -17,6 +17,8 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:text="0"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
||||
android:textSize="24sp" />
|
||||
|
||||
<Button
|
||||
|
||||
@@ -28,13 +28,15 @@
|
||||
android:id="@+id/team_option_logo"
|
||||
android:layout_width="54dp"
|
||||
android:layout_height="54dp"
|
||||
android:layout_margin="3dp"
|
||||
android:layout_margin="2dp"
|
||||
android:scaleType="fitXY"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintDimensionRatio="1:1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:srcCompat="@drawable/ic_robologo" />
|
||||
tools:srcCompat="@drawable/ic_robologo"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/field_option_name"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
[versions]
|
||||
agp = "8.8.0"
|
||||
agp = "8.11.1"
|
||||
asynclayoutinflator = "1.1.0"
|
||||
junit = "4.13.2"
|
||||
junitVersion = "1.1.5"
|
||||
espressoCore = "3.5.1"
|
||||
@@ -10,11 +11,13 @@ lifecycleLivedataKtx = "2.6.1"
|
||||
lifecycleViewmodelKtx = "2.6.1"
|
||||
material3 = "1.3.1"
|
||||
navigationFragment = "2.6.0"
|
||||
navigationFragmentVersion = "2.8.9"
|
||||
navigationUi = "2.6.0"
|
||||
supportAnnotations = "28.0.0"
|
||||
preference = "1.2.1"
|
||||
|
||||
[libraries]
|
||||
asynclayoutinflator = { module = "androidx.asynclayoutinflator:asynclayoutinflator", version.ref = "asynclayoutinflator" }
|
||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
||||
ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
|
||||
espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
|
||||
@@ -25,6 +28,7 @@ lifecycle-livedata-ktx = { group = "androidx.lifecycle", name = "lifecycle-lived
|
||||
lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" }
|
||||
material3 = { module = "androidx.compose.material3:material3", version.ref = "material3" }
|
||||
navigation-fragment = { group = "androidx.navigation", name = "navigation-fragment", version.ref = "navigationFragment" }
|
||||
navigation-fragment-v289 = { module = "androidx.navigation:navigation-fragment", version.ref = "navigationFragmentVersion" }
|
||||
navigation-ui = { group = "androidx.navigation", name = "navigation-ui", version.ref = "navigationUi" }
|
||||
support-annotations = { group = "com.android.support", name = "support-annotations", version.ref = "supportAnnotations" }
|
||||
preference = { group = "androidx.preference", name = "preference", version.ref = "preference" }
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#Sun Mar 24 10:48:55 MDT 2024
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
Reference in New Issue
Block a user