From 888e32f7ecc0a96d1c05c375c39bd7a6346932bc Mon Sep 17 00:00:00 2001 From: kenkeiras Date: Thu, 13 Jul 2017 23:33:19 -0400 Subject: [PATCH] Add a simplistic prototype of wiring mechanism. --- .../minicards/CanvasView.java | 50 ++++++++--- .../minicards/MainActivity.java | 6 +- .../minicards/parts/buttons/RoundButton.java | 88 ++++++++++++++++++- .../parts/{ => samples}/Placeholder.java | 36 +++++++- .../minicards/types/Drawable.java | 7 ++ .../minicards/types/InputConnector.java | 5 ++ .../minicards/types/Moveable.java | 7 ++ .../minicards/types/OutputConnector.java | 9 ++ .../minicards/{parts => types}/Part.java | 13 +-- .../minicards/{parts => }/types/Position.java | 2 +- .../minicards/types/RoundOutputConnector.java | 79 +++++++++++++++++ .../minicards/types/Selectable.java | 6 ++ .../minicards/types/Wire.java | 55 ++++++++++++ 13 files changed, 339 insertions(+), 24 deletions(-) rename app/src/main/java/com/codigoparallevar/minicards/parts/{ => samples}/Placeholder.java (73%) create mode 100644 app/src/main/java/com/codigoparallevar/minicards/types/Drawable.java create mode 100644 app/src/main/java/com/codigoparallevar/minicards/types/InputConnector.java create mode 100644 app/src/main/java/com/codigoparallevar/minicards/types/Moveable.java create mode 100644 app/src/main/java/com/codigoparallevar/minicards/types/OutputConnector.java rename app/src/main/java/com/codigoparallevar/minicards/{parts => types}/Part.java (52%) rename app/src/main/java/com/codigoparallevar/minicards/{parts => }/types/Position.java (82%) create mode 100644 app/src/main/java/com/codigoparallevar/minicards/types/RoundOutputConnector.java create mode 100644 app/src/main/java/com/codigoparallevar/minicards/types/Selectable.java create mode 100644 app/src/main/java/com/codigoparallevar/minicards/types/Wire.java diff --git a/app/src/main/java/com/codigoparallevar/minicards/CanvasView.java b/app/src/main/java/com/codigoparallevar/minicards/CanvasView.java index d9a6a1b..8555d6d 100644 --- a/app/src/main/java/com/codigoparallevar/minicards/CanvasView.java +++ b/app/src/main/java/com/codigoparallevar/minicards/CanvasView.java @@ -1,6 +1,5 @@ package com.codigoparallevar.minicards; -import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; @@ -13,11 +12,13 @@ import android.view.MotionEvent; import android.view.View; import com.codigoparallevar.minicards.motion.MotionMode; -import com.codigoparallevar.minicards.parts.Part; -import com.codigoparallevar.minicards.parts.Placeholder; import com.codigoparallevar.minicards.parts.buttons.RoundButton; -import com.codigoparallevar.minicards.parts.types.Position; -import com.getbase.floatingactionbutton.FloatingActionsMenu; +import com.codigoparallevar.minicards.parts.samples.Placeholder; +import com.codigoparallevar.minicards.types.InputConnector; +import com.codigoparallevar.minicards.types.OutputConnector; +import com.codigoparallevar.minicards.types.Part; +import com.codigoparallevar.minicards.types.Position; +import com.codigoparallevar.minicards.types.Selectable; import org.json.JSONArray; import org.json.JSONException; @@ -35,7 +36,7 @@ class CanvasView extends View { ArrayList parts = new ArrayList<>(); @Nullable - Part selectedPart; + Selectable selectedPart; @Nullable final Position lastTouchedPosition = new Position(); @@ -180,7 +181,9 @@ class CanvasView extends View { } if (motionMode != MotionMode.Type.LongTouch) { if (selectedPart != null){ - selectedPart.touched(); + if (selectedPart instanceof Part){ + ((Part) selectedPart).touched(); + } } } else if (motionMode == MotionMode.Type.LongTouch) { @@ -189,6 +192,9 @@ class CanvasView extends View { Log.d("Canvas", "Deleting element" + selectedPart); parts.remove(selectedPart); } + else { + selectedPart.getMoveable().drop(x, y); + } } } @@ -212,14 +218,15 @@ class CanvasView extends View { Log.i("Canvas", "X: " + x + " Y: " + y + " in drop zone " + _dropZone + " : " + inDropZone(x, y)); if (motionMode == null){ - final Part nowSelectedPart = getPartOn(x, y); + final Selectable nowSelectedPart = getPartOn(x, y); final boolean canWait = selectedPart == nowSelectedPart; motionMode = getMotionMode(canWait); } if (motionMode == MotionMode.Type.LongTouch){ if (selectedPart != null){ _isDragging = true; - selectedPart.move(x, y); + selectedPart.getMoveable().move(x, y); + invalidate(); } } } @@ -288,15 +295,32 @@ class CanvasView extends View { } @Nullable - private Part getPartOn(int x, int y) { - // Look in the list, in reverse so top-most elements are checked before + private Selectable getPartOn(int x, int y) { + // Look in the list of parts, in reverse so top-most elements are checked before for (int i = parts.size() - 1; i >= 0; i--){ final Part part = parts.get(i); - if ((x >= part.getLeft()) && (part.getRight() >= x) - && (y >= part.getTop()) && (part.getBottom() >= y)){ + if (part.containsPoint(x, y)){ return part; } } + + // If no part was found, do the same for connectors + for (int i = parts.size() - 1; i >= 0; i--){ + final Part part = parts.get(i); + // First try with output connectors + for (OutputConnector outputConnector : part.getOutputConnectors()){ + if (outputConnector.containsPoint(x, y)){ + return outputConnector; + } + } + // Then with input ones + for (InputConnector inputConnector : part.getInputConnectors()){ + if (inputConnector.containsPoint(x, y)){ + return inputConnector; + } + } + } + return null; } diff --git a/app/src/main/java/com/codigoparallevar/minicards/MainActivity.java b/app/src/main/java/com/codigoparallevar/minicards/MainActivity.java index eed0677..d0bfd46 100644 --- a/app/src/main/java/com/codigoparallevar/minicards/MainActivity.java +++ b/app/src/main/java/com/codigoparallevar/minicards/MainActivity.java @@ -10,6 +10,7 @@ import android.view.MotionEvent; import android.view.View; import com.codigoparallevar.minicards.parts.buttons.RoundButton; +import com.codigoparallevar.minicards.types.Part; public class MainActivity extends AppCompatActivity { @@ -58,7 +59,10 @@ public class MainActivity extends AppCompatActivity { @Override public void onClick(View v) { if (canvasView != null) { - canvasView.addPart(new RoundButton(500, 500, 50, 100)); + Part part = new RoundButton( + 500, 1200, + 80, 100); + canvasView.addPart(part); } } }); diff --git a/app/src/main/java/com/codigoparallevar/minicards/parts/buttons/RoundButton.java b/app/src/main/java/com/codigoparallevar/minicards/parts/buttons/RoundButton.java index 6c110f2..4742ffc 100644 --- a/app/src/main/java/com/codigoparallevar/minicards/parts/buttons/RoundButton.java +++ b/app/src/main/java/com/codigoparallevar/minicards/parts/buttons/RoundButton.java @@ -3,27 +3,48 @@ package com.codigoparallevar.minicards.parts.buttons; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; +import android.graphics.Path; import android.util.Log; -import com.codigoparallevar.minicards.parts.Part; +import com.codigoparallevar.minicards.types.InputConnector; +import com.codigoparallevar.minicards.types.Moveable; +import com.codigoparallevar.minicards.types.OutputConnector; +import com.codigoparallevar.minicards.types.Part; +import com.codigoparallevar.minicards.types.RoundOutputConnector; import org.json.JSONException; import org.json.JSONObject; -public class RoundButton implements Part { +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +public class RoundButton implements Part { private int _xCenter; private int _yCenter; private final int _innerRadius; private final int _outerRadius; private final int _outerRadiusThickness = 10; + private final int _pathRunWay = 200; + private List _outputConnectors; + private final RoundOutputConnector pressedOuputConnector; public RoundButton(int xCenter, int yCenter, int innerRadius, int outerRadius) { _xCenter = xCenter; _yCenter = yCenter; _innerRadius = innerRadius; _outerRadius = outerRadius; + + // Create connectors + pressedOuputConnector = new RoundOutputConnector( + this, + getOutputConnectorCenterX(), getOutputConnectorCenterY(), + getOutputConnectRadius()); + + _outputConnectors = new LinkedList<>(); + _outputConnectors.add(pressedOuputConnector); + } @Override @@ -54,15 +75,57 @@ public class RoundButton implements Part { Paint backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); backgroundPaint.setColor(Color.BLACK); + if (devMode){ + drawConnector(canvas); + drawWires(canvas, devMode); + } + canvas.drawCircle(_xCenter, _yCenter, _outerRadius, foregroundPaint); canvas.drawCircle(_xCenter, _yCenter, _outerRadius - _outerRadiusThickness, backgroundPaint); canvas.drawCircle(_xCenter, _yCenter, _innerRadius, foregroundPaint); } + private void drawConnector(Canvas canvas) { + Paint connectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + connectorPaint.setColor(Color.RED); + + canvas.drawCircle(getOutputConnectorCenterX(), getOutputConnectorCenterY(), + getOutputConnectRadius(), + connectorPaint); + } + + private int getOutputConnectorCenterX() { + return _xCenter + _outerRadius; + } + + private int getOutputConnectorCenterY() { + return _yCenter; + } + + private int getOutputConnectRadius() { + return _innerRadius / 2; + } + + private void drawWires(Canvas canvas, boolean devMode) { + for (OutputConnector outputConnector : _outputConnectors){ + outputConnector.drawWires(canvas, devMode); + } + } + @Override public void move(int x, int y) { _xCenter = x; _yCenter = y; + + // Move connectors too + pressedOuputConnector.updatePosition( + getOutputConnectorCenterX(), + getOutputConnectorCenterY()); + } + + @Override + public void drop(int x, int y) { + move(x, y); } @Override @@ -70,6 +133,16 @@ public class RoundButton implements Part { Log.d("RoundButton", "Round button touched"); } + @Override + public List getInputConnectors() { + return Collections.emptyList(); + } + + @Override + public List getOutputConnectors() { + return _outputConnectors; + } + @Override public JSONObject serialize() throws JSONException { JSONObject serialized = new JSONObject(); @@ -92,4 +165,15 @@ public class RoundButton implements Part { return new RoundButton(xCenter, yCenter, innerRadius, outerRadius); } + + @Override + public boolean containsPoint(int x, int y) { + return ((Math.abs(x - _xCenter) <= _outerRadius) + && (Math.abs(y - _yCenter) <= _outerRadius)); + } + + @Override + public Moveable getMoveable() { + return this; + } } diff --git a/app/src/main/java/com/codigoparallevar/minicards/parts/Placeholder.java b/app/src/main/java/com/codigoparallevar/minicards/parts/samples/Placeholder.java similarity index 73% rename from app/src/main/java/com/codigoparallevar/minicards/parts/Placeholder.java rename to app/src/main/java/com/codigoparallevar/minicards/parts/samples/Placeholder.java index faa4134..eaf09e7 100644 --- a/app/src/main/java/com/codigoparallevar/minicards/parts/Placeholder.java +++ b/app/src/main/java/com/codigoparallevar/minicards/parts/samples/Placeholder.java @@ -1,13 +1,21 @@ -package com.codigoparallevar.minicards.parts; +package com.codigoparallevar.minicards.parts.samples; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.Log; +import com.codigoparallevar.minicards.types.InputConnector; +import com.codigoparallevar.minicards.types.Moveable; +import com.codigoparallevar.minicards.types.OutputConnector; +import com.codigoparallevar.minicards.types.Part; + import org.json.JSONException; import org.json.JSONObject; +import java.util.Collections; +import java.util.List; + public class Placeholder implements Part { private int _left; private int _top; @@ -72,11 +80,26 @@ public class Placeholder implements Part { _bottom = _top + height; } + @Override + public void drop(int x, int y) { + move(x, y); + } + @Override public void touched() { Log.d("Placeholder", "Placeholder touched"); } + @Override + public List getInputConnectors() { + return Collections.emptyList(); + } + + @Override + public List getOutputConnectors() { + return Collections.emptyList(); + } + @Override public JSONObject serialize() throws JSONException { JSONObject serialized = new JSONObject(); @@ -97,4 +120,15 @@ public class Placeholder implements Part { return new Placeholder(left, top, right, bottom); } + + @Override + public boolean containsPoint(int x, int y) { + return (x >= getLeft()) && (x <= getRight()) + && (y >= getTop()) && (y <= getBottom()); + } + + @Override + public Moveable getMoveable() { + return this; + } } diff --git a/app/src/main/java/com/codigoparallevar/minicards/types/Drawable.java b/app/src/main/java/com/codigoparallevar/minicards/types/Drawable.java new file mode 100644 index 0000000..2557c85 --- /dev/null +++ b/app/src/main/java/com/codigoparallevar/minicards/types/Drawable.java @@ -0,0 +1,7 @@ +package com.codigoparallevar.minicards.types; + +import android.graphics.Canvas; + +public interface Drawable { + void draw(Canvas canvas, boolean devMode); +} diff --git a/app/src/main/java/com/codigoparallevar/minicards/types/InputConnector.java b/app/src/main/java/com/codigoparallevar/minicards/types/InputConnector.java new file mode 100644 index 0000000..d10e2d7 --- /dev/null +++ b/app/src/main/java/com/codigoparallevar/minicards/types/InputConnector.java @@ -0,0 +1,5 @@ +package com.codigoparallevar.minicards.types; + +public interface InputConnector extends Selectable { + void updatePosition(int x, int y); +} diff --git a/app/src/main/java/com/codigoparallevar/minicards/types/Moveable.java b/app/src/main/java/com/codigoparallevar/minicards/types/Moveable.java new file mode 100644 index 0000000..68df24e --- /dev/null +++ b/app/src/main/java/com/codigoparallevar/minicards/types/Moveable.java @@ -0,0 +1,7 @@ +package com.codigoparallevar.minicards.types; + +public interface Moveable { + void move(int x, int y); + + void drop(int x, int y); +} diff --git a/app/src/main/java/com/codigoparallevar/minicards/types/OutputConnector.java b/app/src/main/java/com/codigoparallevar/minicards/types/OutputConnector.java new file mode 100644 index 0000000..bd3e1cf --- /dev/null +++ b/app/src/main/java/com/codigoparallevar/minicards/types/OutputConnector.java @@ -0,0 +1,9 @@ +package com.codigoparallevar.minicards.types; + +import android.graphics.Canvas; + +public interface OutputConnector extends Selectable { + void drop(Wire wire); + void drawWires(Canvas canvas, boolean devMode); + void updatePosition(int x, int y); +} diff --git a/app/src/main/java/com/codigoparallevar/minicards/parts/Part.java b/app/src/main/java/com/codigoparallevar/minicards/types/Part.java similarity index 52% rename from app/src/main/java/com/codigoparallevar/minicards/parts/Part.java rename to app/src/main/java/com/codigoparallevar/minicards/types/Part.java index cd3d79f..0c0fd46 100644 --- a/app/src/main/java/com/codigoparallevar/minicards/parts/Part.java +++ b/app/src/main/java/com/codigoparallevar/minicards/types/Part.java @@ -1,21 +1,22 @@ -package com.codigoparallevar.minicards.parts; +package com.codigoparallevar.minicards.types; import android.graphics.Canvas; import org.json.JSONException; import org.json.JSONObject; -public interface Part { +import java.util.List; + +public interface Part extends Selectable, Moveable, Drawable { int getLeft(); int getRight(); int getTop(); int getBottom(); - void draw(Canvas canvas, boolean devMode); - - void move(int x, int y); - void touched(); + List getInputConnectors(); + List getOutputConnectors(); + JSONObject serialize() throws JSONException; } diff --git a/app/src/main/java/com/codigoparallevar/minicards/parts/types/Position.java b/app/src/main/java/com/codigoparallevar/minicards/types/Position.java similarity index 82% rename from app/src/main/java/com/codigoparallevar/minicards/parts/types/Position.java rename to app/src/main/java/com/codigoparallevar/minicards/types/Position.java index 95bfee2..be985e1 100644 --- a/app/src/main/java/com/codigoparallevar/minicards/parts/types/Position.java +++ b/app/src/main/java/com/codigoparallevar/minicards/types/Position.java @@ -1,4 +1,4 @@ -package com.codigoparallevar.minicards.parts.types; +package com.codigoparallevar.minicards.types; public class Position { private int _x; diff --git a/app/src/main/java/com/codigoparallevar/minicards/types/RoundOutputConnector.java b/app/src/main/java/com/codigoparallevar/minicards/types/RoundOutputConnector.java new file mode 100644 index 0000000..4c66ba6 --- /dev/null +++ b/app/src/main/java/com/codigoparallevar/minicards/types/RoundOutputConnector.java @@ -0,0 +1,79 @@ +package com.codigoparallevar.minicards.types; + +import android.graphics.Canvas; +import android.util.Log; + +import java.util.LinkedList; +import java.util.List; + +public class RoundOutputConnector implements OutputConnector, Drawable { + private int _centerX; + private int _centerY; + private final int _radius; + private final Part _part; + private Wire _currentWire = null; + private final List _wires; + + public RoundOutputConnector(Part part, int centerX, int centerY, int radius) { + _part = part; + _centerX = centerX; + _centerY = centerY; + _radius = radius; + _wires = new LinkedList<>(); + } + + @Override + public boolean containsPoint(int x, int y) { + return ((Math.abs(x - _centerX) <= _radius) + && (Math.abs(y - _centerY) <= _radius)); + } + + + @Override + public Moveable getMoveable() { + if (_currentWire == null) { + startWire(); + } + + return _currentWire; + } + + private void startWire() { + _currentWire = new Wire(this, _centerX, _centerY); + } + + @Override + public void drop(Wire wire) { + if (wire == _currentWire){ + _currentWire = null; + _wires.add(wire); + } + else { + Log.w("RoundOutputConnector", + "Asked to drop non matching wire " + + "(expected " + _currentWire + ", got " + wire + ")"); + } + } + + @Override + public void drawWires(Canvas canvas, boolean devMode) { + for (Wire wire : _wires) { + wire.draw(canvas, devMode); + } + + if (_currentWire != null) { + _currentWire.draw(canvas, devMode); + } + } + + @Override + public void updatePosition(int x, int y) { + _centerX = x; + _centerY = y; + } + + @Override + public void draw(Canvas canvas, boolean devMode) { + + } +} diff --git a/app/src/main/java/com/codigoparallevar/minicards/types/Selectable.java b/app/src/main/java/com/codigoparallevar/minicards/types/Selectable.java new file mode 100644 index 0000000..4d79ddd --- /dev/null +++ b/app/src/main/java/com/codigoparallevar/minicards/types/Selectable.java @@ -0,0 +1,6 @@ +package com.codigoparallevar.minicards.types; + +public interface Selectable { + boolean containsPoint(int x, int y); + Moveable getMoveable(); +} diff --git a/app/src/main/java/com/codigoparallevar/minicards/types/Wire.java b/app/src/main/java/com/codigoparallevar/minicards/types/Wire.java new file mode 100644 index 0000000..c69692b --- /dev/null +++ b/app/src/main/java/com/codigoparallevar/minicards/types/Wire.java @@ -0,0 +1,55 @@ +package com.codigoparallevar.minicards.types; + +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Path; + +public class Wire implements Moveable, Drawable { + private final OutputConnector _dropper; + private final int _xinit; + private final int _yinit; + private int _xend; + private int _yend; + private final static int _pathRunWay = 100; + + public Wire(OutputConnector dropper, int xInit, int yInit) { + super(); + _dropper = dropper; + _xinit = xInit; + _yinit = yInit; + + _xend = xInit; + _yend = yInit; + } + + @Override + public void move(int x, int y) { + _xend = x; + _yend = y; + } + + @Override + public void drop(int x, int y) { + _dropper.drop(this); + } + + @Override + public void draw(Canvas canvas, boolean devMode) { + final Path samplePath = new Path(); + + samplePath.moveTo(_xinit, _yinit); + samplePath.cubicTo( + _xinit + _pathRunWay, _yinit, + _xend - _pathRunWay, _yend, + _xend, _yend); + + Paint pathPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + pathPaint.setColor(Color.GREEN); + pathPaint.setStrokeWidth(5.0f); + pathPaint.setStrokeCap(Paint.Cap.ROUND); + pathPaint.setStyle(Paint.Style.STROKE); + + canvas.drawPath(samplePath, pathPaint); + } +}