diff --git a/app/src/main/java/com/ridgebotics/ridgescout/types/frcTeam.java b/app/src/main/java/com/ridgebotics/ridgescout/types/frcTeam.java index 27e233b..9887259 100644 --- a/app/src/main/java/com/ridgebotics/ridgescout/types/frcTeam.java +++ b/app/src/main/java/com/ridgebotics/ridgescout/types/frcTeam.java @@ -1,21 +1,34 @@ package com.ridgebotics.ridgescout.types; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Color; + import androidx.annotation.NonNull; import com.ridgebotics.ridgescout.utility.AlertManager; import com.ridgebotics.ridgescout.utility.BuiltByteParser; import com.ridgebotics.ridgescout.utility.ByteBuilder; +import java.io.ByteArrayOutputStream; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; public class frcTeam { public static final int typecode = 252; + private static final int[] DEFAULT_COLOR_ARR = new int[]{64,64,64}; + private static final int DEFAULT_COLOR = Color.argb(255, DEFAULT_COLOR_ARR[0],DEFAULT_COLOR_ARR[1],DEFAULT_COLOR_ARR[2]); + public int teamNumber = 0; public String teamName = "null"; public String city = "null"; public String stateOrProv = "null"; public String school = "null"; public String country = "null"; + public Bitmap bitmap = null; + public int[] teamColor = DEFAULT_COLOR_ARR; public int startingYear = 0; public String getDescription(){ @@ -32,6 +45,8 @@ public class frcTeam { .addString(school) .addString(country) .addInt(startingYear) + .addRaw(127, encodeBitmap(bitmap)) + .addIntArray(teamColor) .build(); } catch (ByteBuilder.buildingException e) { AlertManager.error(e); @@ -52,6 +67,13 @@ public class frcTeam { frc.country = (String) objects.get(5).get(); frc.startingYear = (int) objects.get(6).get(); + if(objects.size() == 9){ + frc.bitmap = decodeBitmap((BuiltByteParser.rawObject) objects.get(7)); + frc.teamColor = (int[]) objects.get(8).get(); + +// System.out.println(Arrays.toString(frc.teamColor)); + } + return frc; } catch (BuiltByteParser.byteParsingExeption e) { @@ -60,6 +82,111 @@ public class frcTeam { } } + public static byte[] encodeBitmap(Bitmap bitmap){ + if(bitmap == null) return new byte[]{0}; + ByteArrayOutputStream blob = new ByteArrayOutputStream(); + if(bitmap.compress(Bitmap.CompressFormat.PNG, 0 /* Ignored for PNGs */, blob)){ + return blob.toByteArray(); + }else{ + return new byte[]{0}; + } + } + + public static Bitmap decodeBitmap(BuiltByteParser.rawObject rawObject){ + if(rawObject.getType() != 127) return null; + byte[] bytes = (byte[]) rawObject.get(); + if(bytes.length <= 1) return null; + return BitmapFactory.decodeByteArray(bytes,0,bytes.length); + } + + public static int[] findPrimaryColor(Bitmap bitmap) { + if (bitmap == null) { + return DEFAULT_COLOR_ARR; + } + + // Step 1: Posterize the image (reduce color levels) + Bitmap posterizedBitmap = posterize(bitmap, 8); // 8 levels of posterization + + // Step 2: Find the most saturated and frequent color + return findMostSaturatedAndFrequentColor(posterizedBitmap); + } + + // Posterize the image by reducing color levels + private static Bitmap posterize(Bitmap original, int levels) { + int width = original.getWidth(); + int height = original.getHeight(); + Bitmap posterized = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + + int step = 255 / (levels - 1); + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + int pixel = original.getPixel(x, y); + int r = Color.red(pixel); + int g = Color.green(pixel); + int b = Color.blue(pixel); + + // Quantize the RGB values + r = (r / step) * step; + g = (g / step) * step; + b = (b / step) * step; + + int newPixel = Color.rgb(r, g, b); + posterized.setPixel(x, y, newPixel); + } + } + + return posterized; + } + + // Find the most saturated and frequent color + private static int[] findMostSaturatedAndFrequentColor(Bitmap bitmap) { + int width = bitmap.getWidth(); + int height = bitmap.getHeight(); + Map colorFrequency = new HashMap<>(); + + // Count the frequency of each color + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + int pixel = bitmap.getPixel(x, y); + colorFrequency.put(pixel, colorFrequency.getOrDefault(pixel, 0) + 1); + } + } + + // Find the most saturated and frequent color + int primaryColor = DEFAULT_COLOR; // Default fallback + double maxColorness = -1; + int maxFrequency = 0; + + for (Map.Entry entry : colorFrequency.entrySet()) { + int color = entry.getKey(); + int frequency = entry.getValue(); + float[] hsv = new float[3]; + Color.colorToHSV(color, hsv); + double colorness = Math.pow(hsv[1],2)+Math.pow(hsv[2],2); + + // Prioritize saturation, then frequency + if ((colorness > maxColorness && frequency > maxFrequency * 0.5) && Color.alpha(color) > 127) { //|| (colorness == maxColorness) + maxColorness = colorness; +// maxFrequency = frequency; + primaryColor = color; + } + } + + float[] hsv = new float[3]; + Color.colorToHSV(primaryColor, hsv); + + primaryColor = Color.HSVToColor(new float[]{hsv[0], Math.max(hsv[1], (float) 0.2), Math.max(hsv[2], (float) 0.3)}); + + return new int[]{Color.red(primaryColor),Color.blue(primaryColor),Color.green(primaryColor)}; + } + + public int getTeamColor(){ + return Color.argb(255,teamColor[0],teamColor[2],teamColor[1]); + } + + + @NonNull public String toString(){ return "frcTeam Num: " + teamNumber + ", " + getDescription(); diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/TeamCard.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/TeamCard.java new file mode 100644 index 0000000..088b57f --- /dev/null +++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/TeamCard.java @@ -0,0 +1,108 @@ +package com.ridgebotics.ridgescout.ui; + +import android.content.Context; +import android.graphics.Bitmap; +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.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.Nullable; +import androidx.constraintlayout.widget.ConstraintLayout; + +import com.ridgebotics.ridgescout.R; +import com.ridgebotics.ridgescout.types.frcTeam; + +public class TeamCard extends LinearLayout { + public TeamCard(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + init(context); + } + + public TeamCard(Context context) { + super(context); + init(context); + } + + private TextView teamNumber; + private TextView teamName; + private TextView teamDescription; + + private ImageView teamLogo; + private ConstraintLayout box; + private View coloredBackground; + + public void init(Context context) { + LayoutInflater.from(context).inflate(R.layout.view_team_card, this, true); + + teamNumber = findViewById(R.id.team_card_number); + teamName = findViewById(R.id.team_card_name); + teamLogo = findViewById(R.id.team_card_logo); + teamDescription = findViewById(R.id.team_card_description); + + + box = findViewById(R.id.team_card_box); + coloredBackground = findViewById(R.id.team_card_background); + } + + public void setTeamNumber(int num){ + teamNumber.setText(String.valueOf(num)); + } + + public void setTeamName(String name){ + teamName.setText(name); + } + + public void setTeamLogo(Bitmap bitmap){ + teamLogo.setImageBitmap(bitmap); + } + + public void setTeamDescription(String description){ + teamDescription.setText(description); + } + + public void hideLogo(){ + teamLogo.setVisibility(View.GONE); + } + public void showLogo(){ + teamLogo.setVisibility(View.VISIBLE); + } + + public void fromTeam(frcTeam team){ + setTeamNumber(team.teamNumber); + setTeamName(team.teamName); + + if(team.bitmap != null) { + showLogo(); + setTeamLogo(team.bitmap); + }else{ + hideLogo(); + } + + setTeamDescription(team.getDescription()); + + setColor(team.getTeamColor()); + } + + public void setColor(int color){ + Drawable drawable = box.getBackground(); + drawable.mutate(); + drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP); + + float[] hsv = new float[3]; + Color.colorToHSV(color,hsv); + + coloredBackground.setBackgroundColor( + Color.HSVToColor(127, new float[]{ + hsv[0], + Math.min(hsv[1], 0.75f), + Math.min(hsv[2], 0.5f) + }) + ); + } +} diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/TeamListOption.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/TeamListOption.java new file mode 100644 index 0000000..e5a1d84 --- /dev/null +++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/TeamListOption.java @@ -0,0 +1,99 @@ +package com.ridgebotics.ridgescout.ui; + +import android.content.Context; +import android.graphics.Bitmap; +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.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.Nullable; +import androidx.constraintlayout.widget.ConstraintLayout; + +import com.ridgebotics.ridgescout.R; +import com.ridgebotics.ridgescout.types.frcTeam; + +public class TeamListOption extends LinearLayout { + 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 void init(Context context) { + LayoutInflater.from(context).inflate(R.layout.view_team_option, this, true); + + teamNumber = findViewById(R.id.team_option_number); + teamName = findViewById(R.id.team_option_name); + teamLogo = findViewById(R.id.team_option_logo); + + + box = findViewById(R.id.team_option_box); + coloredBackground = findViewById(R.id.team_option_background); + } + + public void setTeamNumber(int num){ + teamNumber.setText(String.valueOf(num)); + } + + public void setTeamName(String name){ + teamName.setText(name); + } + + public void setTeamLogo(Bitmap bitmap){ + teamLogo.setImageBitmap(bitmap); + } + + public void hideLogo(){ + teamLogo.setVisibility(View.GONE); + } + public void showLogo(){ + teamLogo.setVisibility(View.VISIBLE); + } + + public void fromTeam(frcTeam team){ + setTeamNumber(team.teamNumber); + setTeamName(team.teamName); + + if(team.bitmap != null) { + setTeamLogo(team.bitmap); + }else{ + hideLogo(); + } + + setColor(team.getTeamColor()); + } + + public void setColor(int color){ + Drawable drawable = box.getBackground(); + drawable.mutate(); + drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP); + + float[] hsv = new float[3]; + Color.colorToHSV(color,hsv); + + coloredBackground.setBackgroundColor( + Color.HSVToColor(127, new float[]{ + hsv[0], + Math.min(hsv[1], 0.75f), + Math.min(hsv[2], 0.5f) + }) + ); + } +} diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/TeamSelectorFragment.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/TeamSelectorFragment.java index 0674f88..0e9d20f 100644 --- a/app/src/main/java/com/ridgebotics/ridgescout/ui/TeamSelectorFragment.java +++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/TeamSelectorFragment.java @@ -7,10 +7,7 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.FrameLayout; import android.widget.TableLayout; -import android.widget.TableRow; -import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -89,35 +86,33 @@ public class TeamSelectorFragment extends Fragment { 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); +// 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); - if(!pits_mode || fileEditor.fileExist(evcode + "-" + team.teamNumber + ".pitscoutdata")){ - tr.setBackgroundColor(0x3000FF00); - }else{ - tr.setBackgroundColor(0x30FF0000); + TeamListOption teamRow = new TeamListOption(getContext()); + table.addView(teamRow); + teamRow.fromTeam(team); + + + if(pits_mode) { + if (fileEditor.fileExist(evcode + "-" + team.teamNumber + ".pitscoutdata")) { + teamRow.setColor(0x3000FF00); + } else { + teamRow.setColor(0x30FF0000); + } } - TextView tv = new TextView(getContext()); - tv.setText(String.valueOf(team.teamNumber)); - tv.setTextSize(20); - tr.addView(tv); - - tv = new TextView(getContext()); - tv.setText(team.teamName); - tv.setTextSize(16); - tr.addView(tv); - frcTeam finalTeam = team; - tr.setOnClickListener(v -> { + teamRow.setOnClickListener(v -> { onSelect.onSelect(this, finalTeam); }); } diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/data/TeamsFragment.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/data/TeamsFragment.java index 73b5c6f..dec1313 100644 --- a/app/src/main/java/com/ridgebotics/ridgescout/ui/data/TeamsFragment.java +++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/data/TeamsFragment.java @@ -60,7 +60,7 @@ public class TeamsFragment extends Fragment { options.add("Compiled"); options.add("History"); - binding.dataTypeSpinner.setOptions(options, 0); + binding.dataTypeSpinner.setOptions(options, settingsManager.getDataMode()); binding.dataTypeSpinner.setOnClickListener((item, index) -> { settingsManager.setDataMode(index); @@ -84,12 +84,7 @@ public class TeamsFragment extends Fragment { // ll.setOrientation(LinearLayout.VERTICAL); // binding.teamsArea.addView(ll); - - - - binding.teamName2.setText(String.valueOf(team.teamNumber)); - - binding.teamDescription2.setText(team.getDescription()); + binding.dataTeamCard.fromTeam(team); // tv = new TextView(getContext()); // tv.setLayoutParams(new FrameLayout.LayoutParams( diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/MatchScoutingFragment.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/MatchScoutingFragment.java index 2d0725a..d4d26a0 100644 --- a/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/MatchScoutingFragment.java +++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/MatchScoutingFragment.java @@ -46,11 +46,9 @@ public class MatchScoutingFragment extends Fragment { binding.username.setText(username); binding.alliancePosText.setText(alliance_position); - binding.teamDescription.setVisibility(View.GONE); - binding.teamName.setVisibility(View.GONE); + binding.matchTeamCard.setVisibility(View.GONE); clear_fields(); - binding.teamDescription.setVisibility(View.VISIBLE); - binding.teamName.setVisibility(View.VISIBLE); + binding.matchTeamCard.setVisibility(View.VISIBLE); if(DataManager.match_values == null || DataManager.match_values.length == 0){ TextView tv = new TextView(getContext()); @@ -290,13 +288,12 @@ public class MatchScoutingFragment extends Fragment { if(team == null) { AlertManager.addSimpleError("This team does not exist!"); - binding.teamName.setText("ERROR!"); - binding.teamDescription.setText("ERROR!"); + binding.matchTeamCard.setTeamName("Error!"); + binding.matchTeamCard.setTeamDescription("Error!"); return; } - binding.teamName.setText(team.teamName); - binding.teamDescription.setText(team.getDescription()); + binding.matchTeamCard.fromTeam(team); boolean new_file = !fileEditor.fileExist(filename); diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/PitScoutingFragment.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/PitScoutingFragment.java index 0aab0fd..e28f1e7 100644 --- a/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/PitScoutingFragment.java +++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/scouting/PitScoutingFragment.java @@ -100,12 +100,9 @@ public class PitScoutingFragment extends Fragment { // clear_fields(); binding.pitFileIndicator.setVisibility(View.VISIBLE); - binding.pitTeamName.setVisibility(View.VISIBLE); - binding.pitTeamDescription.setVisibility(View.VISIBLE); - - binding.pitTeamName.setText(team.teamName); - binding.pitTeamDescription.setText(team.getDescription()); + binding.pitsTeamCard.setVisibility(View.VISIBLE); binding.pitBarTeamNum.setText(String.valueOf(team.teamNumber)); + binding.pitsTeamCard.fromTeam(team); filename = evcode + "-" + team.teamNumber + ".pitscoutdata"; diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/TBAFragment.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/TBAFragment.java index bb87019..4929faf 100644 --- a/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/TBAFragment.java +++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/TBAFragment.java @@ -1,6 +1,7 @@ package com.ridgebotics.ridgescout.ui.transfer; import android.app.ProgressDialog; +import android.graphics.Bitmap; import android.os.Bundle; import android.view.Gravity; import android.view.LayoutInflater; @@ -17,6 +18,7 @@ import androidx.fragment.app.Fragment; import com.ridgebotics.ridgescout.databinding.FragmentTransferTbaBinding; import com.ridgebotics.ridgescout.utility.AlertManager; +import com.ridgebotics.ridgescout.utility.ImageRequestTask; import com.ridgebotics.ridgescout.utility.RequestTask; import com.ridgebotics.ridgescout.types.frcEvent; import com.ridgebotics.ridgescout.types.frcMatch; @@ -35,6 +37,7 @@ import java.util.Arrays; import java.util.Calendar; import java.util.Comparator; import java.util.Date; +import java.util.function.Function; public class TBAFragment extends Fragment { private static final String TBAAddress = "https://www.thebluealliance.com/api/v3/"; @@ -87,7 +90,6 @@ public class TBAFragment extends Fragment { } public void eventTable(String dataString){ - stopLoading(); Table.removeAllViews(); Table.setStretchAllColumns(true); @@ -165,7 +167,6 @@ public class TBAFragment extends Fragment { final RequestTask rq = new RequestTask(); rq.onResult(teamsStr -> { - stopLoading(); TableRow tr11 = new TableRow(getContext()); addTableText(tr11, "Downloading Matches..."); Table.addView(tr11); @@ -173,6 +174,7 @@ public class TBAFragment extends Fragment { final RequestTask rq1 = new RequestTask(); rq1.onResult(matchesStr -> { matchTable(matchesStr, teamsStr, j); + stopLoading(); return null; }); rq1.execute((TBAAddress + "event/" + matchKey + "/matches"), TBAHeader); @@ -184,8 +186,11 @@ public class TBAFragment extends Fragment { // tr.addView(cl); Table.addView(tr, rowParams); + toggle = !toggle; } + + stopLoading(); }catch (JSONException j){ AlertManager.error("Failed Downloading", j); stopLoading(); @@ -360,12 +365,7 @@ public class TBAFragment extends Fragment { final ArrayList matchesOBJ = new ArrayList<>(); btn.setOnClickListener(v -> { - if(saveData(matchesOBJ, teamData, eventData)){ - AlertManager.toast("Saved!"); - }else{ - AlertManager.addSimpleError("Error saving files."); - stopLoading(); - } + saveData(matchesOBJ, teamData, eventData); }); @@ -481,53 +481,82 @@ public class TBAFragment extends Fragment { } private boolean saveData(ArrayList matchData, JSONArray teamData, JSONObject eventData){ - try { - final String matchKey = eventData.getString("key"); - String matchName = eventData.getString("short_name"); + startLoading("Saving data..."); - // Sometimes, a short name is not present on TBA Events - if(matchName.isEmpty()){ - matchName = eventData.getString("name"); + Thread t = new Thread(() -> { + try { + final String matchKey = eventData.getString("key"); + String matchName = eventData.getString("short_name"); + + // Sometimes, a short name is not present on TBA Events + if (matchName.isEmpty()) { + matchName = eventData.getString("name"); + } + + startLoading("Saving teams"); + + ArrayList teams = new ArrayList<>(); + for (int i = 0; i < teamData.length(); i++) { + frcTeam teamObj = new frcTeam(); + JSONObject team = teamData.getJSONObject(i); + + teamObj.teamNumber = team.getInt("team_number"); + teamObj.teamName = team.getString("nickname"); + teamObj.city = team.getString("city"); + teamObj.stateOrProv = team.getString("state_prov"); + teamObj.school = team.getString("school_name"); + teamObj.country = team.getString("country"); + teamObj.startingYear = team.getInt("rookie_year"); + + ImageRequestTask imageRequestTask = new ImageRequestTask(); + + imageRequestTask.onResult(bitmap -> { + teamObj.bitmap = bitmap; + teamObj.teamColor = frcTeam.findPrimaryColor(bitmap); + teams.add(teamObj); + + return null; + }); + imageRequestTask.execute("https://www.thebluealliance.com/avatar/" + year + "/frc" + teamObj.teamNumber + ".png"); + } + + while (teams.size() != teamData.length()) { + Thread.sleep(100); + } + + frcEvent event = new frcEvent(); + event.name = matchName; + event.eventCode = matchKey; + event.teams = teams; + event.matches = matchData; + + fileEditor.setEvent(event); + AlertManager.toast("Saved!"); + stopLoading(); + + }catch(Exception j) { + AlertManager.error(j); + stopLoading(); } + }); + t.start(); - - ArrayList teams = new ArrayList<>(); - for(int i=0;i { + if(loadingDialog != null && loadingDialog.isShowing()) + loadingDialog.dismiss(); + loadingDialog = ProgressDialog.show(getActivity(), title, "Please wait..."); + }); } private void stopLoading(){ - if(loadingDialog != null) - loadingDialog.cancel(); - loadingDialog = null; + getActivity().runOnUiThread(() -> { + if (loadingDialog != null) + loadingDialog.cancel(); + loadingDialog = null; + }); } } diff --git a/app/src/main/java/com/ridgebotics/ridgescout/utility/ImageRequestTask.java b/app/src/main/java/com/ridgebotics/ridgescout/utility/ImageRequestTask.java new file mode 100644 index 0000000..ca00868 --- /dev/null +++ b/app/src/main/java/com/ridgebotics/ridgescout/utility/ImageRequestTask.java @@ -0,0 +1,56 @@ +package com.ridgebotics.ridgescout.utility; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.AsyncTask; + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.function.Function; + +import javax.net.ssl.HttpsURLConnection; + +// https://stackoverflow.com/questions/37510411/download-an-image-into-bitmap-file-in-android +public class ImageRequestTask extends AsyncTask { + + Function resultFunction = null; + public static Bitmap getBitmapFromURL(String src) { + try { + URL url = new URL(src); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setDoInput(true); + connection.connect(); + InputStream input = connection.getInputStream(); + return BitmapFactory.decodeStream(input); + } catch (FileNotFoundException e) { + return null; + } catch (IOException e){ + AlertManager.error("Error downloading image " + src, e); + return null; + } + } + + + @Override + protected Bitmap doInBackground(String... params) { + return getBitmapFromURL(params[0]); + } + + public void onResult(Function func) { + this.resultFunction = func; + } + + @Override + protected void onPostExecute(Bitmap result) { + super.onPostExecute(result); + if(resultFunction != null){ + resultFunction.apply(result); + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/ridgebotics/ridgescout/utility/fileEditor.java b/app/src/main/java/com/ridgebotics/ridgescout/utility/fileEditor.java index 4616273..1e97924 100644 --- a/app/src/main/java/com/ridgebotics/ridgescout/utility/fileEditor.java +++ b/app/src/main/java/com/ridgebotics/ridgescout/utility/fileEditor.java @@ -1,6 +1,8 @@ package com.ridgebotics.ridgescout.utility; import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import com.ridgebotics.ridgescout.types.frcEvent; import com.ridgebotics.ridgescout.types.frcTeam; @@ -401,8 +403,13 @@ public final class fileEditor { return filenames; } - - + // https://stackoverflow.com/questions/7620401/how-to-convert-image-file-data-in-a-byte-array-to-a-bitmap +// public static String imageToBitMap(byte[] data) throws IOException { +// Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); +// return bitmap; +// ByteArrayOutputStream blob = new ByteArrayOutputStream(); +// bitmap.compress(Bitmap.CompressFormat.PNG, 0 /* Ignored for PNGs */, blob); +// } public static boolean setTeams(Context context, String key, ArrayList teams){ diff --git a/app/src/main/res/layout/fragment_data_teams.xml b/app/src/main/res/layout/fragment_data_teams.xml index 89eced3..f15e954 100644 --- a/app/src/main/res/layout/fragment_data_teams.xml +++ b/app/src/main/res/layout/fragment_data_teams.xml @@ -23,25 +23,13 @@ android:layout_width="match_parent" android:layout_height="wrap_content" /> - - - - + android:layout_height="wrap_content" /> - diff --git a/app/src/main/res/layout/fragment_scouting_pit.xml b/app/src/main/res/layout/fragment_scouting_pit.xml index bccbb9c..21e2bda 100644 --- a/app/src/main/res/layout/fragment_scouting_pit.xml +++ b/app/src/main/res/layout/fragment_scouting_pit.xml @@ -53,21 +53,12 @@ android:orientation="vertical" android:paddingTop="48dp"> - - - + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> diff --git a/app/src/main/res/layout/view_team_card.xml b/app/src/main/res/layout/view_team_card.xml new file mode 100644 index 0000000..d59af5c --- /dev/null +++ b/app/src/main/res/layout/view_team_card.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/view_team_option.xml b/app/src/main/res/layout/view_team_option.xml new file mode 100644 index 0000000..97f866b --- /dev/null +++ b/app/src/main/res/layout/view_team_option.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + +