diff --git a/app/src/main/java/com/codigoparallevar/minicards/CanvasView.java b/app/src/main/java/com/codigoparallevar/minicards/CanvasView.java index 9ff3ec7..3f45a70 100644 --- a/app/src/main/java/com/codigoparallevar/minicards/CanvasView.java +++ b/app/src/main/java/com/codigoparallevar/minicards/CanvasView.java @@ -107,8 +107,8 @@ class CanvasView extends View implements PartGrid { private Map buildPartsById() { Map partsById = new HashMap<>(parts.size()); for (Part part : parts) { - partsById.put(part.getId(), part); - Log.w("CanvasView", "Added part ID: " + part.getId() + " - " + part); + partsById.put(part.get_id(), part); + Log.w("CanvasView", "Added part ID: " + part.get_id() + " - " + part); } return partsById; @@ -376,6 +376,16 @@ class CanvasView extends View implements PartGrid { return new Tuple2<>(xOffset, yOffset); } + @Override + public void update() { + parentActivity.runOnUiThread(new Runnable() { + @Override + public void run() { + CanvasView.this.invalidate(); + } + }); + } + public int getCardBackgroundColor() { return cardBackgroundColor; } @@ -384,4 +394,16 @@ class CanvasView extends View implements PartGrid { this.cardBackgroundColor = backgroundColor; setBackgroundColor(backgroundColor); } + + public void resume() { + for (Part part : parts) { + part.resume(); + } + } + + public void pause() { + for (Part part : parts) { + part.resume(); + } + } } diff --git a/app/src/main/java/com/codigoparallevar/minicards/CardActivity.java b/app/src/main/java/com/codigoparallevar/minicards/CardActivity.java index 1329cf2..301a64b 100644 --- a/app/src/main/java/com/codigoparallevar/minicards/CardActivity.java +++ b/app/src/main/java/com/codigoparallevar/minicards/CardActivity.java @@ -131,6 +131,14 @@ public class CardActivity extends AppCompatActivity { protected void onResume() { super.onResume(); loadCard(); + canvasView.resume(); + } + + @Override + protected void onPause() { + super.onPause(); + + canvasView.pause(); } private void loadCard() { diff --git a/app/src/main/java/com/codigoparallevar/minicards/CardFile.java b/app/src/main/java/com/codigoparallevar/minicards/CardFile.java index 484d06c..b06fe43 100644 --- a/app/src/main/java/com/codigoparallevar/minicards/CardFile.java +++ b/app/src/main/java/com/codigoparallevar/minicards/CardFile.java @@ -8,6 +8,7 @@ import android.support.annotation.NonNull; import android.util.Log; import com.codigoparallevar.minicards.parts.buttons.RoundButton; +import com.codigoparallevar.minicards.parts.logic.Ticker; import com.codigoparallevar.minicards.parts.samples.ColorBox; import com.codigoparallevar.minicards.parts.samples.Placeholder; import com.codigoparallevar.minicards.types.Part; @@ -258,6 +259,13 @@ public class CardFile { return new Tuple2<>(ColorBox.deserialize(grid, jsonObject.getJSONObject("_data")), Collections.emptyList()); } + else if (type.equals(Ticker.class.getName())){ + Tuple2> buttonInfo = Ticker.deserialize( + grid, + jsonObject.getJSONObject("_data")); + + return buttonInfo; + } else { throw new JSONException("Expected known class, found " + type); } diff --git a/app/src/main/java/com/codigoparallevar/minicards/PartInstantiator.java b/app/src/main/java/com/codigoparallevar/minicards/PartInstantiator.java index 4338730..9328e4d 100644 --- a/app/src/main/java/com/codigoparallevar/minicards/PartInstantiator.java +++ b/app/src/main/java/com/codigoparallevar/minicards/PartInstantiator.java @@ -10,6 +10,8 @@ public abstract class PartInstantiator { public Part build(PartGrid grid) { Tuple2 center = grid.getCenteredOn(); - return instantiate(grid, center); + Part part = instantiate(grid, center); + part.resume(); + return part; } } diff --git a/app/src/main/java/com/codigoparallevar/minicards/PartsHolder.java b/app/src/main/java/com/codigoparallevar/minicards/PartsHolder.java index a772d42..c9266f7 100644 --- a/app/src/main/java/com/codigoparallevar/minicards/PartsHolder.java +++ b/app/src/main/java/com/codigoparallevar/minicards/PartsHolder.java @@ -7,6 +7,7 @@ import android.support.v7.app.AlertDialog; import android.util.Log; import com.codigoparallevar.minicards.parts.buttons.RoundButton; +import com.codigoparallevar.minicards.parts.logic.Ticker; import com.codigoparallevar.minicards.parts.samples.ColorBox; import com.codigoparallevar.minicards.types.Part; import com.codigoparallevar.minicards.types.Tuple2; @@ -20,6 +21,7 @@ class PartsHolder { private final static List> BuiltInParts = new Vector>(){{ add(new Tuple2("Round button", RoundButton.getInstantiator())); + add(new Tuple2("Ticker", Ticker.getInstantiator())); add(new Tuple2("Red/Green box", ColorBox.getInstantiator())); }}; diff --git a/app/src/main/java/com/codigoparallevar/minicards/StubPartGrid.java b/app/src/main/java/com/codigoparallevar/minicards/StubPartGrid.java index c31320a..9bbed58 100644 --- a/app/src/main/java/com/codigoparallevar/minicards/StubPartGrid.java +++ b/app/src/main/java/com/codigoparallevar/minicards/StubPartGrid.java @@ -20,4 +20,8 @@ class StubPartGrid implements PartGrid { public Tuple2 getCenteredOn() { return null; } + + @Override + public void update() { + } } 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 9470f05..e0eef50 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 @@ -38,7 +38,7 @@ public class RoundButton implements Part { private final int _outerRadiusThickness = 10; private final int _pathRunWay = 200; private List _outputConnectors; - private final RoundOutputConnector _pressedOuputConnector; + private final RoundOutputConnector _pressedOutputConnector; private final static int DEFAULT_INNER_RADIUS = 80; private final static int DEFAULT_OUTER_RADIUS = 100; @@ -53,14 +53,14 @@ public class RoundButton implements Part { _outerRadius = outerRadius; // Create connectors - _pressedOuputConnector = new RoundOutputConnector( + _pressedOutputConnector = new RoundOutputConnector( this, _partGrid, getOutputConnectorCenterX(), getOutputConnectorCenterY(), getOutputConnectRadius()); _outputConnectors = new LinkedList<>(); - _outputConnectors.add(_pressedOuputConnector); + _outputConnectors.add(_pressedOutputConnector); } public RoundButton(PartGrid partGrid, int xCenter, int yCenter, int innerRadius, int outerRadius) { @@ -68,22 +68,22 @@ public class RoundButton implements Part { } @Override - public int getLeft() { + public int get_left() { return _xCenter - _outerRadius / 2; } @Override - public int getRight() { + public int get_right() { return _xCenter + _outerRadius / 2; } @Override - public int getTop() { + public int get_top() { return _yCenter - _outerRadius / 2; } @Override - public int getBottom() { + public int get_bottom() { return _yCenter + _outerRadius / 2; } @@ -138,7 +138,7 @@ public class RoundButton implements Part { _yCenter = y; // Move connectors too - _pressedOuputConnector.updatePosition( + _pressedOutputConnector.updatePosition( getOutputConnectorCenterX(), getOutputConnectorCenterY()); } @@ -152,7 +152,7 @@ public class RoundButton implements Part { public void touched() { Log.d("RoundButton", "Round button touched"); - _pressedOuputConnector.sendSignal(); + _pressedOutputConnector.sendSignal(); } @Override @@ -184,7 +184,7 @@ public class RoundButton implements Part { private List> serializeConnectionEndpoints() { List> serializedData = new LinkedList<>(); - for (Tuple2 endpoint : _pressedOuputConnector.getConnectionEndpoints()){ + for (Tuple2 endpoint : _pressedOutputConnector.getConnectionEndpoints()){ serializedData.add(PartConnection.serialize(endpoint.item1, endpoint.item2)); } @@ -197,7 +197,7 @@ public class RoundButton implements Part { } @Override - public String getId() { + public String get_id() { return _id; } @@ -211,8 +211,18 @@ public class RoundButton implements Part { return null; } + @Override + public void resume() { + + } + + @Override + public void pause() { + + } + public RoundOutputConnector getPressedOutputConnector(){ - return _pressedOuputConnector; + return _pressedOutputConnector; } public static Tuple2> deserialize(PartGrid partGrid, JSONObject data) throws JSONException { @@ -230,7 +240,7 @@ public class RoundButton implements Part { JSONArray connectorOuts = data.getJSONArray("on_pressed_output_connector"); for (int i = 0; i < connectorOuts.length(); i++){ connections.add(PartConnection.deserialize( - button._pressedOuputConnector, + button._pressedOutputConnector, connectorOuts.getJSONObject(i))); } diff --git a/app/src/main/java/com/codigoparallevar/minicards/parts/logic/Ticker.java b/app/src/main/java/com/codigoparallevar/minicards/parts/logic/Ticker.java new file mode 100644 index 0000000..fae0d63 --- /dev/null +++ b/app/src/main/java/com/codigoparallevar/minicards/parts/logic/Ticker.java @@ -0,0 +1,297 @@ +package com.codigoparallevar.minicards.parts.logic; + +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Rect; +import android.util.Log; + +import com.codigoparallevar.minicards.PartInstantiator; +import com.codigoparallevar.minicards.ScrolledCanvas; +import com.codigoparallevar.minicards.types.Moveable; +import com.codigoparallevar.minicards.types.Part; +import com.codigoparallevar.minicards.types.PartConnection; +import com.codigoparallevar.minicards.types.PartGrid; +import com.codigoparallevar.minicards.types.RoundInputConnector; +import com.codigoparallevar.minicards.types.RoundOutputConnector; +import com.codigoparallevar.minicards.types.Tuple2; +import com.codigoparallevar.minicards.types.connectors.input.InputConnector; +import com.codigoparallevar.minicards.types.connectors.input.SignalInputConnector; +import com.codigoparallevar.minicards.types.connectors.output.OutputConnector; +import com.codigoparallevar.minicards.utils.Serializations; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +public class Ticker implements Part { + + private static final int DEFAULT_SIDE_SIZE = 100; + private final String _id; + private final PartGrid _partGrid; + private int _left; + private int _top; + private int _right; + private int _bottom; + private List _outputConnectors; + private final RoundOutputConnector _signalOutputConnector; + private final long SLEEP_TIME = 1000; + private Thread _thread = null; + + private Ticker(String id, PartGrid partGrid, int left, int top, int right, int bottom) { + _id = id; + _partGrid = partGrid; + _left = left; + _top = top; + _right = right; + _bottom = bottom; + + // Create connectors + _signalOutputConnector = new RoundOutputConnector( + this, + _partGrid, + getOutputConnectorCenterX(), getOutputConnectorCenterY(), + getOutputConnectRadius()); + + _outputConnectors = new LinkedList<>(); + _outputConnectors.add(_signalOutputConnector); + } + + + public Ticker(PartGrid partGrid, int left, int top, int right, int bottom) { + this(UUID.randomUUID().toString(), partGrid, left, top, right, bottom); + } + + + @Override + public void moveEnd(int x, int y) { + final int width = _right - _left; + final int height = _bottom - _top; + + _left = x - width / 2; + _right = _left + width; + + _top = y - height / 2; + _bottom = _top + height; + + _signalOutputConnector.updatePosition( + getOutputConnectorCenterX(), + getOutputConnectorCenterY()); + } + + @Override + public void drop(int x, int y) { + moveEnd(x, y); + } + + @Override + public boolean containsPoint(int x, int y) { + return (x >= get_left()) && (x <= get_right()) + && (y >= get_top()) && (y <= get_bottom()); + } + + @Override + public Moveable getMoveable() { + return this; + } + + @Override + public void unlink() { + pause(); + + for (InputConnector input : getSignalInputConnectors()) { + input.unlink(); + } + } + + @Override + public void draw(ScrolledCanvas canvas, boolean devMode) { + Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); + paint.setColor(Color.GRAY); + + if (devMode){ + drawConnector(canvas); + drawWires(canvas, devMode); + } + + + canvas.drawRect( + new Rect(_left, _top, + _right, _bottom), + paint); + } + + private void drawConnector(ScrolledCanvas canvas) { + Paint connectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + connectorPaint.setColor(Color.RED); + + canvas.drawCircle(_right, getOutputConnectorCenterY(), + getOutputConnectRadius(), + connectorPaint); + } + + private void drawWires(ScrolledCanvas canvas, boolean devMode) { + for (OutputConnector outputConnector : _outputConnectors){ + outputConnector.drawWires(canvas, devMode); + } + } + + @Override + public int get_left() { + return _left; + } + + @Override + public int get_right() { + return _right; + } + + @Override + public int get_top() { + return _top; + } + + @Override + public int get_bottom() { + return _bottom; + } + + @Override + public void touched() { + // Just ignore it, as it's a logic component + } + + @Override + public List getSignalInputConnectors() { + return Collections.emptyList(); + } + + @Override + public List getOutputConnectors() { + return _outputConnectors; + } + + @Override + public JSONObject serialize() throws JSONException { + JSONObject serialized = new JSONObject(); + + serialized.put("id", _id); + serialized.put("left", _left); + serialized.put("top", _top); + serialized.put("right", _right); + serialized.put("bottom", _bottom); + serialized.put("on_signal_output_connector", + Serializations.serialize(serializeConnectionEndpoints())); + + return serialized; + } + + public static Tuple2> deserialize(PartGrid partGrid, JSONObject data) throws JSONException { + String id = data.getString("id"); + int left = data.getInt("left"); + int top = data.getInt("top"); + int right = data.getInt("right"); + int bottom = data.getInt("bottom"); + + Ticker ticker = new Ticker(id, partGrid, left, top, right, bottom); + + List connections = new LinkedList<>(); + + JSONArray connectorOuts = data.getJSONArray("on_signal_output_connector"); + for (int i = 0; i < connectorOuts.length(); i++){ + connections.add(PartConnection.deserialize( + ticker._signalOutputConnector, + connectorOuts.getJSONObject(i))); + } + + return new Tuple2>(ticker, connections); + } + + private List> serializeConnectionEndpoints() { + List> serializedData = new LinkedList<>(); + + for (Tuple2 endpoint : _signalOutputConnector.getConnectionEndpoints()){ + serializedData.add(PartConnection.serialize(endpoint.item1, endpoint.item2)); + } + + return serializedData; + } + + @Override + public void sendSignal(RoundInputConnector roundInputConnector) { + // @TODO: REMOVE THE NEED FOR THIS + } + + @Override + public String get_id() { + return _id; + } + + @Override + public InputConnector getConnectorWithId(String inputConnectorId) { + return null; + } + + @Override + public String getConnectorId(InputConnector inputConnector) { + return null; + } + + @Override + public void resume() { + _thread = new Thread(new Runnable() { + @Override + public void run() { + while (Ticker.this._thread == Thread.currentThread()) { + Ticker.this._signalOutputConnector.sendSignal(); + _partGrid.update(); + + try { + Thread.sleep(SLEEP_TIME); + } catch (InterruptedException e) { + Log.e("Minicards Ticker", "Wait failed", e); + Ticker.this._thread = null; + return; + } + } + } + }); + + _thread.start(); + } + + @Override + public void pause() { + _thread = null; + } + + + private int getOutputConnectorCenterX() { + return _right; + } + + private int getOutputConnectorCenterY() { + return (_top + _bottom) / 2; + } + + private int getOutputConnectRadius() { + return (_right - _left) / 2; + } + + public static PartInstantiator getInstantiator() { + final int halfSideSize = DEFAULT_SIDE_SIZE / 2; + return new PartInstantiator() { + @Override + protected Part instantiate(PartGrid grid, Tuple2 center) { + return new Ticker(grid, + center.item1 - halfSideSize, center.item2 - halfSideSize, + center.item1 + halfSideSize, center.item2 + halfSideSize); + } + }; + } +} diff --git a/app/src/main/java/com/codigoparallevar/minicards/parts/samples/ColorBox.java b/app/src/main/java/com/codigoparallevar/minicards/parts/samples/ColorBox.java index c441d0a..dec65d3 100644 --- a/app/src/main/java/com/codigoparallevar/minicards/parts/samples/ColorBox.java +++ b/app/src/main/java/com/codigoparallevar/minicards/parts/samples/ColorBox.java @@ -61,22 +61,22 @@ public class ColorBox implements Part { } @Override - public int getLeft() { + public int get_left() { return _left; } @Override - public int getRight() { + public int get_right() { return _right; } @Override - public int getTop() { + public int get_top() { return _top; } @Override - public int getBottom() { + public int get_bottom() { return _bottom; } @@ -171,7 +171,7 @@ public class ColorBox implements Part { } @Override - public String getId() { + public String get_id() { return _id; } @@ -195,6 +195,16 @@ public class ColorBox implements Part { return null; } + @Override + public void resume() { + + } + + @Override + public void pause() { + + } + public static Part deserialize(PartGrid partGrid, JSONObject data) throws JSONException { String id = data.getString("id"); int left = data.getInt("left"); @@ -207,8 +217,8 @@ public class ColorBox implements Part { @Override public boolean containsPoint(int x, int y) { - return (x >= getLeft()) && (x <= getRight()) - && (y >= getTop()) && (y <= getBottom()); + return (x >= get_left()) && (x <= get_right()) + && (y >= get_top()) && (y <= get_bottom()); } @Override @@ -224,15 +234,15 @@ public class ColorBox implements Part { } public int getInputConnectorCenterX() { - return getLeft(); + return get_left(); } private int getInputConnectRadius() { - return (getRight() - getLeft()) / 2; + return (get_right() - get_left()) / 2; } public int getInputConnectorCenterY() { - return (getTop() + getBottom()) / 2; + return (get_top() + get_bottom()) / 2; } public static PartInstantiator getInstantiator() { diff --git a/app/src/main/java/com/codigoparallevar/minicards/parts/samples/Placeholder.java b/app/src/main/java/com/codigoparallevar/minicards/parts/samples/Placeholder.java index e78cc1e..72ae38d 100644 --- a/app/src/main/java/com/codigoparallevar/minicards/parts/samples/Placeholder.java +++ b/app/src/main/java/com/codigoparallevar/minicards/parts/samples/Placeholder.java @@ -42,22 +42,22 @@ public class Placeholder implements Part { } @Override - public int getLeft() { + public int get_left() { return _left; } @Override - public int getRight() { + public int get_right() { return _right; } @Override - public int getTop() { + public int get_top() { return _top; } @Override - public int getBottom() { + public int get_bottom() { return _bottom; } @@ -131,7 +131,7 @@ public class Placeholder implements Part { } @Override - public String getId() { + public String get_id() { return _id; } @@ -145,6 +145,16 @@ public class Placeholder implements Part { return null; } + @Override + public void resume() { + + } + + @Override + public void pause() { + + } + public static Part deserialize(PartGrid partGrid, JSONObject data) throws JSONException { String id = data.getString("id"); int left = data.getInt("left"); @@ -157,8 +167,8 @@ public class Placeholder implements Part { @Override public boolean containsPoint(int x, int y) { - return (x >= getLeft()) && (x <= getRight()) - && (y >= getTop()) && (y <= getBottom()); + return (x >= get_left()) && (x <= get_right()) + && (y >= get_top()) && (y <= get_bottom()); } @Override diff --git a/app/src/main/java/com/codigoparallevar/minicards/types/Part.java b/app/src/main/java/com/codigoparallevar/minicards/types/Part.java index 3dc11ae..d16d459 100644 --- a/app/src/main/java/com/codigoparallevar/minicards/types/Part.java +++ b/app/src/main/java/com/codigoparallevar/minicards/types/Part.java @@ -10,10 +10,10 @@ import org.json.JSONObject; import java.util.List; public interface Part extends Selectable, Moveable, Drawable { - int getLeft(); - int getRight(); - int getTop(); - int getBottom(); + int get_left(); + int get_right(); + int get_top(); + int get_bottom(); void touched(); @@ -24,10 +24,12 @@ public interface Part extends Selectable, Moveable, Drawable { void sendSignal(RoundInputConnector roundInputConnector); - String getId(); + String get_id(); InputConnector getConnectorWithId(String inputConnectorId); String getConnectorId(InputConnector inputConnector); + void resume(); + void pause(); } diff --git a/app/src/main/java/com/codigoparallevar/minicards/types/PartGrid.java b/app/src/main/java/com/codigoparallevar/minicards/types/PartGrid.java index ad098be..92517f5 100644 --- a/app/src/main/java/com/codigoparallevar/minicards/types/PartGrid.java +++ b/app/src/main/java/com/codigoparallevar/minicards/types/PartGrid.java @@ -8,4 +8,6 @@ public interface PartGrid { SignalInputConnector getSignalInputConnectorOn(int x, int y); Tuple2 getCenteredOn(); + + void update(); } diff --git a/app/src/main/java/com/codigoparallevar/minicards/types/RoundOutputConnector.java b/app/src/main/java/com/codigoparallevar/minicards/types/RoundOutputConnector.java index 7c5a254..a8c32ff 100644 --- a/app/src/main/java/com/codigoparallevar/minicards/types/RoundOutputConnector.java +++ b/app/src/main/java/com/codigoparallevar/minicards/types/RoundOutputConnector.java @@ -119,7 +119,7 @@ public class RoundOutputConnector implements Drawable, SignalOutputConnector { for (SignalWire wire : _wires) { InputConnector inputConnector = wire.getAttachedTo(); Part endPart = inputConnector.getPart(); - endpointIds.add(new Tuple2<>(inputConnector.getId(), endPart.getId())); + endpointIds.add(new Tuple2<>(inputConnector.getId(), endPart.get_id())); } return endpointIds;