From b264a3bb73f2dc2f8d97e5890f7b211c239614e3 Mon Sep 17 00:00:00 2001 From: Michael Mikovsky <77305074+Astatin3@users.noreply.github.com> Date: Sun, 2 Feb 2025 11:50:24 -0700 Subject: [PATCH] Add checkbox --- .../ridgescout/ui/BackgroundView.java | 208 ++++++++++++++++++ .../ui/transfer/FileSelectorFragment.java | 14 +- .../fragment_transfer_file_selector.xml | 2 +- 3 files changed, 221 insertions(+), 3 deletions(-) create mode 100644 app/src/main/java/com/ridgebotics/ridgescout/ui/BackgroundView.java diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/BackgroundView.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/BackgroundView.java new file mode 100644 index 0000000..75ba8e0 --- /dev/null +++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/BackgroundView.java @@ -0,0 +1,208 @@ +package com.ridgebotics.ridgescout.ui; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.ColorMatrixColorFilter; +import android.graphics.LinearGradient; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.RectF; +import android.graphics.Shader; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewTreeObserver; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +public class BackgroundView extends View { + private List circles; + private Paint whitePaint; + private Paint greenPaint; + private Random random; + + // Physics simulation constants + private static final float GRAVITY = 9.8f; + private static final float DAMPING = 0.5f; + private static final float CIRCLE_SPAWN_INTERVAL = 500; // milliseconds + private long lastSpawnTime = 0; + + // Screen dimensions + private int screenWidth; + private int screenHeight; + + public BackgroundView(Context context, AttributeSet attrs) { + super(context, attrs); + initialize(); + } + + private void initialize() { + // Setup paints + whitePaint = new Paint(); + whitePaint.setColor(Color.WHITE); + whitePaint.setStyle(Paint.Style.STROKE); + whitePaint.setStrokeWidth(2); + + greenPaint = new Paint(); + greenPaint.setColor(Color.GREEN); + greenPaint.setStyle(Paint.Style.FILL); + + circles = new ArrayList<>(); + random = new Random(); + + // Get screen dimensions after layout + ViewTreeObserver vto = getViewTreeObserver(); + vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + screenWidth = getWidth(); + screenHeight = getHeight(); + getViewTreeObserver().removeOnGlobalLayoutListener(this); + } + }); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + // Spawn new circles periodically + long currentTime = System.currentTimeMillis(); + if (currentTime - lastSpawnTime > CIRCLE_SPAWN_INTERVAL) { + spawnCircle(); + lastSpawnTime = currentTime; + } + + // First pass: detect all collisions + List collisions = new ArrayList<>(); + for (int i = 0; i < circles.size(); i++) { + Circle circle = circles.get(i); + + // Wall and floor collisions + if (circle.x - circle.radius < 0) { + circle.x = circle.radius; + circle.velocityX *= -DAMPING; + } + if (circle.x + circle.radius > screenWidth) { + circle.x = screenWidth - circle.radius; + circle.velocityX *= -DAMPING; + } + if (circle.y + circle.radius > screenHeight) { + circle.y = screenHeight - circle.radius; + circle.velocityY = 0; + } + + // Detect collisions with other circles + for (int j = i + 1; j < circles.size(); j++) { + Circle otherCircle = circles.get(j); + float dx = otherCircle.x - circle.x; + float dy = otherCircle.y - circle.y; + float distance = (float) Math.sqrt(dx * dx + dy * dy); + + if (distance < circle.radius + otherCircle.radius) { + collisions.add(new Collision(circle, otherCircle, dx, dy, distance)); + } + } + + // Apply gravity + circle.velocityY += GRAVITY * 0.1f; + } + + // Second pass: resolve collisions + for (Collision collision : collisions) { + Circle c1 = collision.circle1; + Circle c2 = collision.circle2; + float dx = collision.dx; + float dy = collision.dy; + float distance = collision.distance; + + // Calculate overlap + float overlap = (c1.radius + c2.radius - distance) / 2; + + // Separate circles + float separationX = overlap * dx / distance; + float separationY = overlap * dy / distance; + + c1.x -= separationX; + c1.y -= separationY; + c2.x += separationX; + c2.y += separationY; + + // Dampen velocities + c1.velocityX *= DAMPING; + c1.velocityY *= DAMPING; + c2.velocityX *= DAMPING; + c2.velocityY *= DAMPING; + } + + // Draw and update circles + Iterator iterator = circles.iterator(); + while (iterator.hasNext()) { + Circle circle = iterator.next(); + + // Update position + circle.x += circle.velocityX; + circle.y += circle.velocityY; + + // Draw circle + Paint paint = circle.isGreen ? greenPaint : whitePaint; + canvas.drawCircle(circle.x, circle.y, circle.radius, paint); + + // Remove circles that have fallen off screen + if (circle.y > screenHeight + circle.radius) { + iterator.remove(); + } + } + + // Trigger redraw + invalidate(); + } + + // Collision tracking class + private static class Collision { + Circle circle1, circle2; + float dx, dy, distance; + + Collision(Circle c1, Circle c2, float dx, float dy, float distance) { + this.circle1 = c1; + this.circle2 = c2; + this.dx = dx; + this.dy = dy; + this.distance = distance; + } + } + + private void spawnCircle() { + // More likely to spawn white circles + boolean isGreen = random.nextFloat() < 0.2f; + + float radius = isGreen ? + 120: // Green: 20-60 + 80; // White: 10-30 + + float x = random.nextFloat() * screenWidth; + float velocityX = (random.nextFloat() - 0.5f) * 5; + + circles.add(new Circle(x, -radius, radius, velocityX, 0, isGreen)); + } + + // Circle class to represent individual circles + private static class Circle { + float x, y; + float radius; + float velocityX, velocityY; + boolean isGreen; + + Circle(float x, float y, float radius, float velocityX, float velocityY, boolean isGreen) { + this.x = x; + this.y = y; + this.radius = radius; + this.velocityX = velocityX; + this.velocityY = velocityY; + this.isGreen = isGreen; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/FileSelectorFragment.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/FileSelectorFragment.java index 8efc9f6..38d799c 100644 --- a/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/FileSelectorFragment.java +++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/FileSelectorFragment.java @@ -6,6 +6,7 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.CheckBox; import android.widget.FrameLayout; import android.widget.TableLayout; import android.widget.TableRow; @@ -66,6 +67,10 @@ public class FileSelectorFragment extends Fragment { tr.setBackgroundColor(background_color); + CheckBox checkBox = new CheckBox(getContext()); + checkBox.setChecked(true); + tr.addView(checkBox); + TextView tv = new TextView(getContext()); tv.setText(String.valueOf(files[i])); tv.setTextSize(20); @@ -77,6 +82,7 @@ public class FileSelectorFragment extends Fragment { selected_arr[fi] = sel; tr.setBackgroundColor(sel ? background_color : unselected_background_color); + ((CheckBox) tr.getChildAt(0)).setChecked(sel); }); } @@ -88,9 +94,12 @@ public class FileSelectorFragment extends Fragment { Arrays.fill(selected_arr, Boolean.TRUE); for(int i = 0; i < files.length; i++){ - View child = binding.fileSelectorTable.getChildAt(i); + TableRow child = (TableRow) binding.fileSelectorTable.getChildAt(i); child.setBackgroundColor(background_color); - child.setVisibility(is_in_search_param(files[i], search_param, match_num_nums) ? View.VISIBLE : View.GONE); + boolean sel = is_in_search_param(files[i], search_param, match_num_nums); + child.setVisibility(sel ? View.VISIBLE : View.GONE); + ((CheckBox) child.getChildAt(0)).setChecked(sel); + } return false; @@ -103,6 +112,7 @@ public class FileSelectorFragment extends Fragment { View child = binding.fileSelectorTable.getChildAt(i); if(child.getVisibility() == View.VISIBLE && selected_arr[i]) filenames.add(files[i]); + } onSelect.onSelect(get_bytes_of_filenames(filenames)); }); diff --git a/app/src/main/res/layout/fragment_transfer_file_selector.xml b/app/src/main/res/layout/fragment_transfer_file_selector.xml index 7386707..25045da 100644 --- a/app/src/main/res/layout/fragment_transfer_file_selector.xml +++ b/app/src/main/res/layout/fragment_transfer_file_selector.xml @@ -16,7 +16,6 @@