diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 28f25e0..5ab980f 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -53,5 +53,6 @@ dependencies { // implementation("com.github.yuriy-budiyev:code-scanner:2.3.0") // implementation("com.github.kenglxn.QRGen:android:3.0.1") - implementation("com.journeyapps:zxing-android-embedded:2.3.0") +// implementation("com.journeyapps:zxing-android-embedded:2.3.0") + implementation("com.dlazaro66.qrcodereaderview:qrcodereaderview:2.0.3") } \ No newline at end of file diff --git a/app/src/main/java/com/astatin3/scoutingapp2025/RequestTask.java b/app/src/main/java/com/astatin3/scoutingapp2025/RequestTask.java index cc1d95b..3db6682 100644 --- a/app/src/main/java/com/astatin3/scoutingapp2025/RequestTask.java +++ b/app/src/main/java/com/astatin3/scoutingapp2025/RequestTask.java @@ -1,6 +1,13 @@ package com.astatin3.scoutingapp2025; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.PointF; import android.os.AsyncTask; +import android.util.AttributeSet; +import android.view.View; import java.io.BufferedReader; import java.io.IOException; diff --git a/app/src/main/java/com/astatin3/scoutingapp2025/qrPointsOverlayView.java b/app/src/main/java/com/astatin3/scoutingapp2025/qrPointsOverlayView.java new file mode 100644 index 0000000..6d4e733 --- /dev/null +++ b/app/src/main/java/com/astatin3/scoutingapp2025/qrPointsOverlayView.java @@ -0,0 +1,53 @@ +package com.astatin3.scoutingapp2025; + +// From https://github.com/dlazaro66/QRCodeReaderView/blob/master/samples/src/main/java/com/example/qr_readerexample/PointsOverlayView.java + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.PointF; +import android.util.AttributeSet; +import android.view.View; + +public class qrPointsOverlayView extends View { + + PointF[] points; + private Paint paint; + + public qrPointsOverlayView(Context context) { + super(context); + init(); + } + + public qrPointsOverlayView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public qrPointsOverlayView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(); + } + + private void init() { + paint = new Paint(); + paint.setColor(Color.YELLOW); + paint.setStyle(Paint.Style.FILL); + } + + public void setPoints(PointF[] points) { + this.points = points; + invalidate(); + } + + @Override + public void draw(Canvas canvas) { + super.draw(canvas); + if (points != null) { + for (PointF pointF : points) { + canvas.drawCircle(pointF.x, pointF.y, 10, paint); + } + } + } +} diff --git a/app/src/main/java/com/astatin3/scoutingapp2025/ui/TBA/TBAFragment.java b/app/src/main/java/com/astatin3/scoutingapp2025/ui/TBA/TBAFragment.java index 67899ec..96d53b3 100644 --- a/app/src/main/java/com/astatin3/scoutingapp2025/ui/TBA/TBAFragment.java +++ b/app/src/main/java/com/astatin3/scoutingapp2025/ui/TBA/TBAFragment.java @@ -44,239 +44,18 @@ public class TBAFragment extends Fragment { alert.create().show(); } -// abstract class TBATask extends RequestTask { -// public static void run(String... uri){ -// super.execute(uri); -// } -// private void response(String result){ -// alert("data", result); -// } -// } + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { -// TBAViewModel dashboardViewModel = -// new ViewModelProvider(this).get(TBAViewModel.class); binding = FragmentTbaBinding.inflate(inflater, container, false); View root = binding.getRoot(); - ScrollArea = binding.ScrollArea; - Table = binding.matchTable; - - warnPopup(); - return root; } - public void warnPopup() { - -// alert("App Title", "This is an alert with no consequence"); -// - AlertDialog.Builder alert = new AlertDialog.Builder(getContext()); - alert.setMessage("This is an alert with no consequence"); - alert.setTitle("App Title"); - alert.setCancelable(true); - - alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - final RequestTask rq = new RequestTask(); - rq.onResult(new Function() { - @Override - public String apply(String s) { - eventTable(s); - return null; - } - }); - rq.execute(TBAAddress + "events/2024", TBAHeader); - } - }); - - alert.create().show(); - } - - private void addTableText(TableRow tr, String textStr){ - TextView text = new TextView(getContext()); - text.setTextSize(18); - text.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); // Text align center - text.setText(textStr); - tr.addView(text); - } - - public void eventTable(String dataString){ - try { - JSONArray data = new JSONArray(dataString); - - Table.setStretchAllColumns(true); - Table.bringToFront(); - - boolean toggle = false; - - TableRow tr = new TableRow(getContext()); - addTableText(tr, "Key"); - addTableText(tr, "Title"); - addTableText(tr, "Type"); - - Table.addView(tr); - - for(int i=0;i() { - @Override - public String apply(String s) { - matchTable(s); - return null; - } - }); - rq.execute((TBAAddress + "event/" + matchKey + "/matches"), TBAHeader); - } - }); - button.setText(matchKey); - tr.addView(button); - - String name = j.getString("short_name"); - - // Sometimes, a short name is not present on TBA Events - if(name.isEmpty()){ - name = j.getString("name"); - } - - addTableText(tr, name); - addTableText(tr, j.getString("event_type_string")); - -// tr.addView(text); - Table.addView(tr); - - toggle = !toggle; - } - }catch (JSONException j){ - alert("Error", "Invalid JSON"); - } - } - - class matchComparator implements Comparator - { - - public int compare(JSONObject a, JSONObject b) - { - try { - return a.getInt("match_number") - b.getInt("match_number"); - }catch (JSONException j){ - return 0; - } - } - } - - - public void matchTable(String dataString){ - try { - JSONArray data = new JSONArray(dataString); - - Table.removeAllViews(); - Table.setStretchAllColumns(true); - Table.bringToFront(); - - - - if(data.length() == 0){ - TableRow tr = new TableRow(getContext()); - addTableText(tr, "This event has no matches released yet..."); - Table.addView(tr); - tr = new TableRow(getContext()); - addTableText(tr, "Try manually adding practice matches."); - Table.addView(tr); - return; - } - - - TableRow tr = new TableRow(getContext()); - addTableText(tr, "#"); - addTableText(tr, "Red-1"); - addTableText(tr, "Red-2"); - addTableText(tr, "Red-3"); - addTableText(tr, "Blue-1"); - addTableText(tr, "Blue-2"); - addTableText(tr, "Blue-3"); - Table.addView(tr); - - - data = JSONUtil.sort(data, new Comparator(){ - public int compare(Object a, Object b){ - JSONObject ja = (JSONObject)a; - JSONObject jb = (JSONObject)b; - try { - return ja.getInt("match_number") - jb.getInt("match_number"); - }catch (JSONException j){ - return 0; - } - } - }); - - - boolean toggle = false; - int matchCount = 1; - - for(int a=0;a qrBitmaps; - - private void alert(String title, String content) { - AlertDialog.Builder alert = new AlertDialog.Builder(getContext()); - alert.setMessage(content); - alert.setTitle(title); - alert.setPositiveButton("OK", null); - alert.setCancelable(true); - alert.create().show(); - } - - public static Bitmap generateQrCode(String myCodeText) throws WriterException { -// Hashtable hintMap = new Hashtable(); - - QRCodeWriter qrCodeWriter = new QRCodeWriter(); - - Map hints = new EnumMap(EncodeHintType.class); - hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); - hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); // H = 30% damage - hints.put(EncodeHintType.QR_COMPACT, true); - hints.put(EncodeHintType.MARGIN, 0); /* default = 4 */ - - int size = 200; - - BitMatrix bitMatrix = qrCodeWriter.encode(myCodeText, BarcodeFormat.QR_CODE, size, size, hints); - - int width = bitMatrix.getWidth(); - int height = bitMatrix.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] = bitMatrix.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; - } - - public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { binding = FragmentHomeBinding.inflate(inflater, container, false); View root = binding.getRoot(); - -// binding.qrSizeSlider.setProgress(qrSize); - - sendData("Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, DisestablishmenjAWHRJGQWEhugQWHKJEtarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, DisestablishmenjAWHRJGQWEhugQWHKJEtarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, DisestablishmenjAWHRJGQWEhugQWHKJEtarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, DisestablishmenjAWHRJGQWEhugQWHKJEtarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, DisestablishmenjAWHRJGQWEhugQWHKJEtarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism,Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, DisestablishmenjAWHRJGQWEhugQWHKJEtarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, DisestablishmentarianismDisestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, DisestablishmenjAWHRJGQWEhugQWHKJEtarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, DisestablishmentarianismDisestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, DisestablishmenjAWHRJGQWEhugQWHKJEtarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, DisestablishmentarianismDisestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, DisestablishmenjAWHRJGQWEhugQWHKJEtarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, DisestablishmentarianismDisestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, DisestablishmenjAWHRJGQWEhugQWHKJEtarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, DisestablishmentarianismDisestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, DisestablishmenjAWHRJGQWEhugQWHKJEtarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism, Disestablishmentarianism"); - return root; } - - private void sendData(String data){ - minQrSize = Math.round(maxQrCount/data.length()); - - binding.qrSizeSlider.setMax(maxQrSize-minQrSize); - binding.qrSpeedSlider.setMax((minQrSpeed-maxQrSpeed)*2); - - binding.qrSpeedSlider.setProgress(defaultQrDelay); - - qrCount = (data.length()/qrSize)+1; - binding.qrIndexD.setText(String.valueOf(qrCount)); - -// alert("size", ""+binding.qrSizeSlider.getProgress()+"\n"+binding.qrSizeSlider.getMax()); - - binding.qrSpeedSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - qrDelay = -(minQrSpeed - progress - maxQrSpeed + 1); - } - @Override - public void onStartTrackingTouch(SeekBar seekBar) {} - @Override - public void onStopTrackingTouch(SeekBar seekBar) {} - }); - - binding.qrSizeSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {} - @Override - public void onStartTrackingTouch(SeekBar seekBar) {} - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - qrSize = seekBar.getProgress() + minQrSpeed; - qrCount = (data.length()/qrSize)+1; - binding.qrIndexD.setText(String.valueOf(qrCount)); - sendData(data); - } - }); - - qrBitmaps = new ArrayList(); - for(int i=0;i<=(data.length()/qrSize);i++){ - final int start = i*qrSize; - int end = (i+1)*qrSize; - if(end > data.length()){ - end = data.length()-1; - } - try { - qrBitmaps.add(generateQrCode( - data.substring(start, end) - )); - }catch (WriterException e){ - e.printStackTrace(); - } - } - qrIndex = 0; - if(timer != null){ - timer.cancel(); - } - qrLoop(); - } - - private void updateQr(){ - binding.qrImage.setImageBitmap(qrBitmaps.get(qrIndex)); - if(qrDelay > 0) { - this.qrIndex += 1; - if (this.qrIndex >= this.qrCount) { - this.qrIndex = 0; - } - }else{ - this.qrIndex -= 1; - if (this.qrIndex < 0) { - this.qrIndex = this.qrCount-1; - } - } - binding.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(); - } - }.start(); - - - } } \ No newline at end of file diff --git a/app/src/main/java/com/astatin3/scoutingapp2025/ui/notifications/NotificationsFragment.java b/app/src/main/java/com/astatin3/scoutingapp2025/ui/notifications/NotificationsFragment.java deleted file mode 100644 index b456ece..0000000 --- a/app/src/main/java/com/astatin3/scoutingapp2025/ui/notifications/NotificationsFragment.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.astatin3.scoutingapp2025.ui.notifications; - -import android.app.Activity; -import android.app.AlertDialog; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; - -import com.astatin3.scoutingapp2025.R; -import com.budiyev.android.codescanner.CodeScanner; -import com.budiyev.android.codescanner.CodeScannerView; -import com.budiyev.android.codescanner.DecodeCallback; -import com.budiyev.android.codescanner.ScanMode; -import com.google.zxing.DecodeHintType; -import com.google.zxing.EncodeHintType; -import com.google.zxing.Result; - -import java.util.EnumMap; -import java.util.Hashtable; -import java.util.Map; - -public class NotificationsFragment extends Fragment { - private CodeScanner mCodeScanner; - - - private void alert(String title, String content) { - AlertDialog.Builder alert = new AlertDialog.Builder(getContext()); - alert.setMessage(content); - alert.setTitle(title); - alert.setPositiveButton("OK", null); - alert.setCancelable(true); - alert.create().show(); - } - - @Nullable - @Override - public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState) { - final Activity activity = getActivity(); - View root = inflater.inflate(R.layout.fragment_notifications, container, false); - - IntentIntegrator integrator = IntentIntegrator.forSupportFragment(FragmentQRScan.this); - - integrator.setOrientationLocked(false); - integrator.setPrompt("Scan QR code"); - integrator.setBeepEnabled(false); - integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE); - - - integrator.initiateScan(); - - return root; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/astatin3/scoutingapp2025/ui/transfer/TBAView.java b/app/src/main/java/com/astatin3/scoutingapp2025/ui/transfer/TBAView.java new file mode 100644 index 0000000..da83c65 --- /dev/null +++ b/app/src/main/java/com/astatin3/scoutingapp2025/ui/transfer/TBAView.java @@ -0,0 +1,254 @@ +package com.astatin3.scoutingapp2025.ui.transfer; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.os.Bundle; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ScrollView; +import android.widget.TableRow; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import com.astatin3.scoutingapp2025.R; +import com.astatin3.scoutingapp2025.RequestTask; +import com.astatin3.scoutingapp2025.databinding.FragmentTbaBinding; +import com.astatin3.scoutingapp2025.databinding.FragmentTransferBinding; +import com.astatin3.scoutingapp2025.ui.JSONUtil; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Comparator; +import java.util.function.Function; + +public class TBAView extends ScrollView { + + // private final String + private final String TBAAddress = "https://www.thebluealliance.com/api/v3/"; + private final String TBAHeader = "X-TBA-Auth-Key: tjEKSZojAU2pgbs2mBt06SKyOakVhLutj3NwuxLTxPKQPLih11aCIwRIVFXKzY4e"; + + private android.widget.TableLayout Table; + + public TBAView(Context context) { + super(context); + } + + public TBAView(Context context, AttributeSet attributeSet){ + super(context, attributeSet); + } + + private void alert(String title, String content) { + AlertDialog.Builder alert = new AlertDialog.Builder(getContext()); + alert.setMessage(content); + alert.setTitle(title); + alert.setPositiveButton("OK", null); + alert.setCancelable(true); + alert.create().show(); + } + + + public void start(FragmentTransferBinding binding, String yearStr) { + + Table = binding.matchTable; + + final RequestTask rq = new RequestTask(); + rq.onResult(new Function() { + @Override + public String apply(String s) { + eventTable(s); + return null; + } + }); + rq.execute(TBAAddress + "events/"+yearStr, TBAHeader); + + } + + private void addTableText(TableRow tr, String textStr){ + TextView text = new TextView(getContext()); + text.setTextSize(18); + text.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); // Text align center + text.setText(textStr); + tr.addView(text); + } + + public void eventTable(String dataString){ + try { + JSONArray data = new JSONArray(dataString); + + Table.setStretchAllColumns(true); + Table.bringToFront(); + + boolean toggle = false; + + TableRow tr = new TableRow(getContext()); + addTableText(tr, "Key"); + addTableText(tr, "Title"); + addTableText(tr, "Type"); + + Table.addView(tr); + + for(int i=0;i() { + @Override + public String apply(String s) { + matchTable(s); + return null; + } + }); + rq.execute((TBAAddress + "event/" + matchKey + "/matches"), TBAHeader); + } + }); + button.setText(matchKey); + tr.addView(button); + + String name = j.getString("short_name"); + + // Sometimes, a short name is not present on TBA Events + if(name.isEmpty()){ + name = j.getString("name"); + } + + addTableText(tr, name); + addTableText(tr, j.getString("event_type_string")); + +// tr.addView(text); + Table.addView(tr); + + toggle = !toggle; + } + }catch (JSONException j){ + alert("Error", "Invalid JSON"); + } + } + + class matchComparator implements Comparator + { + + public int compare(JSONObject a, JSONObject b) + { + try { + return a.getInt("match_number") - b.getInt("match_number"); + }catch (JSONException j){ + return 0; + } + } + } + + + public void matchTable(String dataString){ + try { + JSONArray data = new JSONArray(dataString); + + Table.removeAllViews(); + Table.setStretchAllColumns(true); + Table.bringToFront(); + + + + if(data.length() == 0){ + TableRow tr = new TableRow(getContext()); + addTableText(tr, "This event has no matches released yet..."); + Table.addView(tr); + tr = new TableRow(getContext()); + addTableText(tr, "Try manually adding practice matches."); + Table.addView(tr); + return; + } + + + TableRow tr = new TableRow(getContext()); + addTableText(tr, "#"); + addTableText(tr, "Red-1"); + addTableText(tr, "Red-2"); + addTableText(tr, "Red-3"); + addTableText(tr, "Blue-1"); + addTableText(tr, "Blue-2"); + addTableText(tr, "Blue-3"); + Table.addView(tr); + + + data = JSONUtil.sort(data, new Comparator(){ + public int compare(Object a, Object b){ + JSONObject ja = (JSONObject)a; + JSONObject jb = (JSONObject)b; + try { + return ja.getInt("match_number") - jb.getInt("match_number"); + }catch (JSONException j){ + return 0; + } + } + }); + + + boolean toggle = false; + int matchCount = 1; + + for(int a=0;a qrBitmaps; + public generatorView(Context context) { + super(context); + } + + public generatorView(Context context, AttributeSet attributeSet){ + super(context, attributeSet); + } + + public static Bitmap generateQrCode(String myCodeText) throws WriterException { + + QRCodeWriter qrCodeWriter = new QRCodeWriter(); + + Map hints = new EnumMap(EncodeHintType.class); + hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); // H = 30% damage +// hints.put(EncodeHintType.QR_COMPACT, true); + hints.put(EncodeHintType.MARGIN, 0); /* default = 4 */ + + int size = 200; + + BitMatrix bitMatrix = qrCodeWriter.encode(myCodeText, BarcodeFormat.QR_CODE, size, size, hints); + + int width = bitMatrix.getWidth(); + int height = bitMatrix.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] = bitMatrix.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; + } + + public void start(FragmentTransferBinding binding, String data){ + qrImage = binding.qrImage; + qrSpeedSlider = binding.qrSpeedSlider; + qrSizeSlider = binding.qrSizeSlider; + qrIndexN = binding.qrIndexN; + qrIndexD = binding.qrIndexD; + + sendData(data); + } + + private void sendData(String data){ + minQrSize = Math.round(data.length()/maxQrCount); + + qrSizeSlider.setMax(maxQrSize-minQrSize); + qrSpeedSlider.setMax((minQrSpeed-maxQrSpeed)*2); + + 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); + } + @Override + public void onStartTrackingTouch(SeekBar seekBar) {} + @Override + public void onStopTrackingTouch(SeekBar seekBar) {} + }); + + qrSizeSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {} + @Override + public void onStartTrackingTouch(SeekBar seekBar) {} + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + qrSize = seekBar.getProgress() + minQrSpeed; + qrCount = (data.length()/qrSize)+1; + qrIndexD.setText(String.valueOf(qrCount)); + sendData(data); + } + }); + + qrSpeedSlider.setProgress(defaultQrDelay+5); + + qrBitmaps = new ArrayList(); + for(int i=0;i<=(data.length()/qrSize);i++){ + final int start = i*qrSize; + int end = (i+1)*qrSize; + if(end > data.length()){ + end = data.length()-1; + } + try { + qrBitmaps.add(generateQrCode( + data.substring(start, end) + )); + }catch (WriterException e){ + e.printStackTrace(); + } + } + qrIndex = 0; + if(timer != null){ + timer.cancel(); + } + qrLoop(); + } + + private void updateQr(){ + qrImage.setImageBitmap(qrBitmaps.get(qrIndex)); + if(qrDelay > 0) { + this.qrIndex += 1; + if (this.qrIndex >= this.qrCount) { + this.qrIndex = 0; + } + }else{ + this.qrIndex -= 1; + if (this.qrIndex < 0) { + this.qrIndex = this.qrCount-1; + } + } + 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(); + } + }.start(); + } +} diff --git a/app/src/main/java/com/astatin3/scoutingapp2025/ui/transfer/scannerView.java b/app/src/main/java/com/astatin3/scoutingapp2025/ui/transfer/scannerView.java new file mode 100644 index 0000000..c8295ff --- /dev/null +++ b/app/src/main/java/com/astatin3/scoutingapp2025/ui/transfer/scannerView.java @@ -0,0 +1,66 @@ +package com.astatin3.scoutingapp2025.ui.transfer; + +import android.app.ActionBar; +import android.content.Context; +import android.graphics.PointF; +import android.util.AttributeSet; +import android.view.View; + +import androidx.constraintlayout.widget.ConstraintLayout; + +import com.astatin3.scoutingapp2025.databinding.FragmentTransferBinding; +import com.astatin3.scoutingapp2025.qrPointsOverlayView; +import com.dlazaro66.qrcodereaderview.QRCodeReaderView; + +public class scannerView extends ConstraintLayout { + private QRCodeReaderView qrCodeReaderView; + private qrPointsOverlayView pointsOverlayView; + + private class codeReadListener implements QRCodeReaderView.OnQRCodeReadListener { + @Override + public void onQRCodeRead(String text, PointF[] points) { + pointsOverlayView.setPoints(points); + } + } + + public scannerView(Context context) { + super(context); + } + + public scannerView(Context context, AttributeSet attributeSet){ + super(context, attributeSet); + } + + public void start(FragmentTransferBinding binding){ + qrCodeReaderView = new QRCodeReaderView(getContext()); + this.addView(qrCodeReaderView); + ConstraintLayout.LayoutParams qrCodeReaderViewParams = (ConstraintLayout.LayoutParams) qrCodeReaderView.getLayoutParams(); + qrCodeReaderViewParams.width = ActionBar.LayoutParams.MATCH_PARENT; + qrCodeReaderViewParams.height = ActionBar.LayoutParams.MATCH_PARENT; + qrCodeReaderView.setLayoutParams(qrCodeReaderViewParams); + + pointsOverlayView = new qrPointsOverlayView(getContext()); + pointsOverlayView.bringToFront(); + this.addView(pointsOverlayView); + ConstraintLayout.LayoutParams pointsOverlayViewParams = (ConstraintLayout.LayoutParams) qrCodeReaderView.getLayoutParams(); + pointsOverlayViewParams.width = ActionBar.LayoutParams.MATCH_PARENT; + pointsOverlayViewParams.height = ActionBar.LayoutParams.MATCH_PARENT; + pointsOverlayView.setLayoutParams(pointsOverlayViewParams); + + + qrCodeReaderView.startCamera(); + +// qrCodeReaderView = (QRCodeReaderView) binding.qrdecoderview; + qrCodeReaderView.setOnQRCodeReadListener(new codeReadListener()); +// qrCodeReaderView.setQRDecodingEnabled(true); + qrCodeReaderView.setAutofocusInterval(2000L); +// qrCodeReaderView.setFrontCamera(); + qrCodeReaderView.setBackCamera(); + qrCodeReaderView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + qrCodeReaderView.forceAutoFocus(); + } + }); + } +} diff --git a/app/src/main/res/drawable/transfer_icon.xml b/app/src/main/res/drawable/transfer_icon.xml new file mode 100644 index 0000000..115dfc1 --- /dev/null +++ b/app/src/main/res/drawable/transfer_icon.xml @@ -0,0 +1,16 @@ + + + + diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 29fb527..dc993a5 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -10,84 +10,5 @@ android:focusableInTouchMode="false" tools:context=".MainActivity"> - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_notifications.xml b/app/src/main/res/layout/fragment_notifications.xml deleted file mode 100644 index 8939324..0000000 --- a/app/src/main/res/layout/fragment_notifications.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_transfer.xml b/app/src/main/res/layout/fragment_transfer.xml new file mode 100644 index 0000000..cccd728 --- /dev/null +++ b/app/src/main/res/layout/fragment_transfer.xml @@ -0,0 +1,171 @@ + + + + + +