Add support for static value blocks.

This commit is contained in:
Sergio Martínez Portela 2020-06-01 20:29:28 +02:00
parent af9352de42
commit 4ecd4936bd
23 changed files with 627 additions and 107 deletions

View File

@ -13,7 +13,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.codigoparallevar.minicards.motion.MotionMode; import com.codigoparallevar.minicards.motion.MotionMode;
import com.codigoparallevar.minicards.parts.connectors.SignalRoundOutputConnector; import com.codigoparallevar.minicards.parts.connectors.ProgramakerCustomBlockInputConnector;
import com.codigoparallevar.minicards.types.Part; import com.codigoparallevar.minicards.types.Part;
import com.codigoparallevar.minicards.types.PartConnection; import com.codigoparallevar.minicards.types.PartConnection;
import com.codigoparallevar.minicards.types.PartGrid; import com.codigoparallevar.minicards.types.PartGrid;
@ -185,7 +185,15 @@ public class CanvasView extends View implements PartGrid {
final int xInCanvas = xInScreen + _viewOrigin.item1; final int xInCanvas = xInScreen + _viewOrigin.item1;
final int yInCanvas = yInScreen + _viewOrigin.item2; final int yInCanvas = yInScreen + _viewOrigin.item2;
switch (event.getAction()){ int action = event.getAction();
if ((action == MotionEvent.ACTION_MOVE)
&& _devMode
&& (selectedPart instanceof Wire)) {
// Wires cannot be moved, so go into "move canvas" mode
selectedPart = null;
}
switch (action){
case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_DOWN:
{ {
_mouseDownPoint = new Tuple2<>(xInScreen, yInScreen); _mouseDownPoint = new Tuple2<>(xInScreen, yInScreen);
@ -197,19 +205,8 @@ public class CanvasView extends View implements PartGrid {
Log.d(LogTag, "Touched part not found"); Log.d(LogTag, "Touched part not found");
return false; return false;
} }
if (selectedPart instanceof Wire) {
// No drag or long-touch, just show the "cut" option
// TODO:
Log.d(LogTag, "Touched Wire");
Wire selectedWire = (Wire) selectedPart;
selectedPart = null;
selectedWire.unlink();
}
else {
Log.d(LogTag, "Touched part FOUND. Part: " + selectedPart); Log.d(LogTag, "Touched part FOUND. Part: " + selectedPart);
} }
}
break; break;
case MotionEvent.ACTION_UP: case MotionEvent.ACTION_UP:
@ -222,9 +219,23 @@ public class CanvasView extends View implements PartGrid {
if (selectedPart instanceof Part){ if (selectedPart instanceof Part){
((Part) selectedPart).touched(); ((Part) selectedPart).touched();
} }
else if (selectedPart instanceof Wire) {
// TODO: No drag or long-touch, just show the "cut" option
Log.d(LogTag, "Touched Wire");
Wire selectedWire = (Wire) selectedPart;
selectedPart = null;
selectedWire.unlink();
}
else if (selectedPart instanceof ProgramakerCustomBlockInputConnector) {
((ProgramakerCustomBlockInputConnector) selectedPart).touched();
}
} }
} }
else if (motionMode == MotionMode.Type.LongTouch && _devMode) { else if (motionMode == MotionMode.Type.LongTouch && _devMode) {
if (selectedPart instanceof Wire) {
// Wires cannot be moved, so go into the
}
if (selectedPart != null) { if (selectedPart != null) {
selectedPart.getMoveable().drop(xInCanvas, yInCanvas); selectedPart.getMoveable().drop(xInCanvas, yInCanvas);
@ -351,15 +362,15 @@ public class CanvasView extends View implements PartGrid {
} }
} }
// // Then with input ones // Then with input ones
// List<InputConnector> inputConnectors = part.getInputConnectors(); List<InputConnector> inputConnectors = part.getInputConnectors();
// if (inputConnectors != null) { if (inputConnectors != null) {
// for (InputConnector inputConnector : inputConnectors) { for (InputConnector inputConnector : inputConnectors) {
// if (inputConnector.containsPoint(x, y)) { if (inputConnector.containsPoint(x, y)) {
// return inputConnector; return inputConnector;
// } }
// } }
// } }
} }
// Finally, try with the wires // Finally, try with the wires
@ -545,11 +556,8 @@ public class CanvasView extends View implements PartGrid {
@Override @Override
public void update() { public void update() {
parentActivity.runOnUiThread(new Runnable() { parentActivity.runOnUiThread(() -> {
@Override
public void run() {
CanvasView.this.invalidate(); CanvasView.this.invalidate();
}
}); });
} }

View File

@ -15,6 +15,7 @@ import com.codigoparallevar.minicards.parts.logic.Toggle;
import com.codigoparallevar.minicards.parts.samples.ColorBox; import com.codigoparallevar.minicards.parts.samples.ColorBox;
import com.codigoparallevar.minicards.parts.samples.Placeholder; import com.codigoparallevar.minicards.parts.samples.Placeholder;
import com.codigoparallevar.minicards.parts.strings.ConvertToString; import com.codigoparallevar.minicards.parts.strings.ConvertToString;
import com.codigoparallevar.minicards.parts.values.StaticValuePart;
import com.codigoparallevar.minicards.types.Part; import com.codigoparallevar.minicards.types.Part;
import com.codigoparallevar.minicards.types.PartConnection; import com.codigoparallevar.minicards.types.PartConnection;
import com.codigoparallevar.minicards.types.PartGrid; import com.codigoparallevar.minicards.types.PartGrid;
@ -293,6 +294,13 @@ public class CardFile {
return customBlockPartInfo; return customBlockPartInfo;
} }
else if (type.equals(StaticValuePart.class.getName())){
Tuple2<Part, List<PartConnection>> staticValuePartInfo = StaticValuePart.deserialize(
grid,
jsonObject.getJSONObject("_data"));
return staticValuePartInfo;
}
else { else {
throw new JSONException("Expected known class, found " + type); throw new JSONException("Expected known class, found " + type);
} }

View File

@ -67,7 +67,6 @@ public class SignalListenerManager implements ProgramakerSignalListener {
} }
private void onDisconnect(String bridgeId, String key) { private void onDisconnect(String bridgeId, String key) {
Log.w(LogTag, "Connection lost to (bridge="+bridgeId+",key="+key + ")");
Tuple2<String, String> id = new Tuple2<>(bridgeId, key); Tuple2<String, String> id = new Tuple2<>(bridgeId, key);
// Check that there is still someone listening // Check that there is still someone listening

View File

@ -7,7 +7,7 @@ import android.os.AsyncTask;
import android.util.Log; import android.util.Log;
import com.codigoparallevar.minicards.ScrolledCanvas; import com.codigoparallevar.minicards.ScrolledCanvas;
import com.codigoparallevar.minicards.parts.connectors.AnyRoundInputConnector; import com.codigoparallevar.minicards.parts.connectors.ProgramakerCustomBlockInputConnector;
import com.codigoparallevar.minicards.parts.connectors.AnyRoundOutputConnector; import com.codigoparallevar.minicards.parts.connectors.AnyRoundOutputConnector;
import com.codigoparallevar.minicards.parts.connectors.ConnectorTypeInfo; import com.codigoparallevar.minicards.parts.connectors.ConnectorTypeInfo;
import com.codigoparallevar.minicards.parts.connectors.RoundOutputConnector; import com.codigoparallevar.minicards.parts.connectors.RoundOutputConnector;
@ -48,7 +48,7 @@ public class ProgramakerCustomBlockPart implements Part, ProgramakerSignalListen
private static final int IO_PADDING = 20; private static final int IO_PADDING = 20;
private static final String LogTag = "PM Custom block part"; private static final String LogTag = "PM Custom block part";
private List<Tuple2<ConnectorTypeInfo, AnyRoundInputConnector>> inputConnectors = null; private List<Tuple2<ConnectorTypeInfo, ProgramakerCustomBlockInputConnector>> inputConnectors = null;
private List<Tuple2<ConnectorTypeInfo, RoundOutputConnector>> outputConnectors = null; private List<Tuple2<ConnectorTypeInfo, RoundOutputConnector>> outputConnectors = null;
private final PartGrid _partGrid; private final PartGrid _partGrid;
@ -141,16 +141,18 @@ public class ProgramakerCustomBlockPart implements Part, ProgramakerSignalListen
final boolean has_pulse_output = has_pulse_input || type.equals("trigger"); final boolean has_pulse_output = has_pulse_input || type.equals("trigger");
final boolean hasImplicitOutput = type.equals("getter"); final boolean hasImplicitOutput = type.equals("getter");
final List<Tuple2<ConnectorTypeInfo, AnyRoundInputConnector>> inputs = new LinkedList<>(); final List<Tuple2<ConnectorTypeInfo, ProgramakerCustomBlockInputConnector>> inputs = new LinkedList<>();
final List<Tuple2<ConnectorTypeInfo, RoundOutputConnector>> outputs = new LinkedList<>(); final List<Tuple2<ConnectorTypeInfo, RoundOutputConnector>> outputs = new LinkedList<>();
SignalRoundOutputConnector pulseOutput = null; SignalRoundOutputConnector pulseOutput = null;
// Add pulses // Add pulses
if (has_pulse_input) { if (has_pulse_input) {
inputs.add(new Tuple2<>(new ConnectorTypeInfo(ConnectorTypeInfo.Type.PULSE), ConnectorTypeInfo typeInfo = new ConnectorTypeInfo(ConnectorTypeInfo.Type.PULSE);
new AnyRoundInputConnector(this, 0, 0, inputs.add(new Tuple2<>(typeInfo,
IO_RADIUS)) new ProgramakerCustomBlockInputConnector(this, _partGrid,
0, 0,
IO_RADIUS, typeInfo))
); );
} }
if (has_pulse_output) { if (has_pulse_output) {
@ -185,8 +187,11 @@ public class ProgramakerCustomBlockPart implements Part, ProgramakerSignalListen
savedTo = arg; savedTo = arg;
} }
else { else {
inputs.add(new Tuple2<>(ConnectorTypeInfo.FromTypeName(arg.getType()), ConnectorTypeInfo typeInfo = ConnectorTypeInfo.FromTypeName(arg.getType());
new AnyRoundInputConnector(this, 0, 0, IO_RADIUS))); inputs.add(new Tuple2<>(typeInfo,
new ProgramakerCustomBlockInputConnector(this, _partGrid,
0, 0,
IO_RADIUS, typeInfo)));
} }
} }
} }
@ -218,7 +223,7 @@ public class ProgramakerCustomBlockPart implements Part, ProgramakerSignalListen
// Update inputs // Update inputs
int y = get_top(); int y = get_top();
int x = get_left() + IO_PADDING; int x = get_left() + IO_PADDING;
for (Tuple2<ConnectorTypeInfo, AnyRoundInputConnector> entry : inputConnectors) { for (Tuple2<ConnectorTypeInfo, ProgramakerCustomBlockInputConnector> entry : inputConnectors) {
InputConnector input = entry.item2; InputConnector input = entry.item2;
int new_x = x + IO_PADDING + IO_RADIUS / 2; int new_x = x + IO_PADDING + IO_RADIUS / 2;
input.updatePosition(new_x, y); input.updatePosition(new_x, y);
@ -250,7 +255,7 @@ public class ProgramakerCustomBlockPart implements Part, ProgramakerSignalListen
@Override @Override
public List<InputConnector> getInputConnectors() { public List<InputConnector> getInputConnectors() {
List<InputConnector> result = new ArrayList<>(inputConnectors.size()); List<InputConnector> result = new ArrayList<>(inputConnectors.size());
for (Tuple2<ConnectorTypeInfo, AnyRoundInputConnector> entry : inputConnectors) { for (Tuple2<ConnectorTypeInfo, ProgramakerCustomBlockInputConnector> entry : inputConnectors) {
result.add(entry.item2); result.add(entry.item2);
} }
@ -385,7 +390,7 @@ public class ProgramakerCustomBlockPart implements Part, ProgramakerSignalListen
List<String> arguments = new LinkedList<>(); List<String> arguments = new LinkedList<>();
int index = -1; int index = -1;
for (Tuple2<ConnectorTypeInfo, AnyRoundInputConnector> entry : inputConnectors) { for (Tuple2<ConnectorTypeInfo, ProgramakerCustomBlockInputConnector> entry : inputConnectors) {
index++; index++;
if (entry.item1.get_type() == ConnectorTypeInfo.Type.PULSE) { if (entry.item1.get_type() == ConnectorTypeInfo.Type.PULSE) {
continue; continue;
@ -480,7 +485,7 @@ public class ProgramakerCustomBlockPart implements Part, ProgramakerSignalListen
private int getConnectorIndex(InputConnector inputConnector) { private int getConnectorIndex(InputConnector inputConnector) {
int index = 0; int index = 0;
for (Tuple2<ConnectorTypeInfo, AnyRoundInputConnector> entry : inputConnectors) { for (Tuple2<ConnectorTypeInfo, ProgramakerCustomBlockInputConnector> entry : inputConnectors) {
if (entry.item2 == inputConnector) { if (entry.item2 == inputConnector) {
return index; return index;
} }
@ -501,7 +506,7 @@ public class ProgramakerCustomBlockPart implements Part, ProgramakerSignalListen
} }
public ConnectorTypeInfo getConnectorInfo(InputConnector inputConnector) { public ConnectorTypeInfo getConnectorInfo(InputConnector inputConnector) {
for (Tuple2<ConnectorTypeInfo, AnyRoundInputConnector> entry : inputConnectors) { for (Tuple2<ConnectorTypeInfo, ProgramakerCustomBlockInputConnector> entry : inputConnectors) {
if (entry.item2 == inputConnector) { if (entry.item2 == inputConnector) {
return entry.item1; return entry.item1;
} }
@ -579,8 +584,6 @@ public class ProgramakerCustomBlockPart implements Part, ProgramakerSignalListen
@Override @Override
public void draw(ScrolledCanvas canvas, boolean devMode) { public void draw(ScrolledCanvas canvas, boolean devMode) {
updateWidthHeight(); // TODO: Remove after the calculations have stabilized
if (!devMode) { if (!devMode) {
return; // Logic block, don't show on user-mode return; // Logic block, don't show on user-mode
} }
@ -611,7 +614,7 @@ public class ProgramakerCustomBlockPart implements Part, ProgramakerSignalListen
private void drawConnectors(ScrolledCanvas canvas) { private void drawConnectors(ScrolledCanvas canvas) {
if (inputConnectors != null) { if (inputConnectors != null) {
for (Tuple2<ConnectorTypeInfo, AnyRoundInputConnector> entry : inputConnectors) { for (Tuple2<ConnectorTypeInfo, ProgramakerCustomBlockInputConnector> entry : inputConnectors) {
Paint outerInputConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG); Paint outerInputConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
outerInputConnectorPaint.setColor(entry.item1.getOuterColor()); outerInputConnectorPaint.setColor(entry.item1.getOuterColor());

View File

@ -4,7 +4,6 @@ import android.util.Log;
import com.codigoparallevar.minicards.ScrolledCanvas; import com.codigoparallevar.minicards.ScrolledCanvas;
import com.codigoparallevar.minicards.types.Drawable; import com.codigoparallevar.minicards.types.Drawable;
import com.codigoparallevar.minicards.types.Moveable;
import com.codigoparallevar.minicards.types.Part; import com.codigoparallevar.minicards.types.Part;
import com.codigoparallevar.minicards.types.PartGrid; import com.codigoparallevar.minicards.types.PartGrid;
import com.codigoparallevar.minicards.types.connectors.Wiring.AnyWire; import com.codigoparallevar.minicards.types.connectors.Wiring.AnyWire;
@ -47,7 +46,7 @@ public class AnyRoundOutputConnector implements Drawable, AnyOutputConnector,
@Override @Override
public Moveable getMoveable() { public AnyWire getMoveable() {
if (_currentWire == null) { if (_currentWire == null) {
startWire(); startWire();
} }
@ -56,21 +55,26 @@ public class AnyRoundOutputConnector implements Drawable, AnyOutputConnector,
} }
@Override @Override
public void unlink() {} public void unlink() {
while (_wires.size() > 0) {
_wires.get(0).unlink();
}
}
private void startWire() { private void startWire() {
_currentWire = new AnyWire(this, _centerX, _centerY); _currentWire = new AnyWire(this, _centerX, _centerY);
} }
@Override public void drop(AnyWire wire, AnyInputConnector resultPoint) {
public void drop(AnyWire wire) { if (wire != _currentWire) {
Log.w("RoundOutputConnector",
"Asked to drop non matching wire "
+ "(expected " + _currentWire + ", got " + wire + ")");
return ;
}
if (wire == _currentWire){
_currentWire = null; _currentWire = null;
AnyInputConnector resultPoint = _partGrid.getAnyInputConnectorOn(
wire.getXEnd(), wire.getYEnd());
Log.d("RoundOutputConnector", "Dropped wire on " + resultPoint); Log.d("RoundOutputConnector", "Dropped wire on " + resultPoint);
// Not connected // Not connected
@ -87,15 +91,25 @@ public class AnyRoundOutputConnector implements Drawable, AnyOutputConnector,
wire.attachTo(resultPoint, this); wire.attachTo(resultPoint, this);
_wires.add(wire); _wires.add(wire);
} }
else {
@Override
public void drop(AnyWire wire) {
if (wire != _currentWire) {
Log.w("RoundOutputConnector", Log.w("RoundOutputConnector",
"Asked to drop non matching wire " "Asked to drop non matching wire "
+ "(expected " + _currentWire + ", got " + wire + ")"); + "(expected " + _currentWire + ", got " + wire + ")");
return;
} }
AnyInputConnector resultPoint = _partGrid.getAnyInputConnectorOn(
wire.getXEnd(), wire.getYEnd());
drop(wire, resultPoint);
} }
@Override @Override
public void unlinkWire(AnyWire wire) { public void wireUnlinked(AnyWire wire) {
_wires.remove(wire); _wires.remove(wire);
_connections.remove(wire.getAttachedTo()); _connections.remove(wire.getAttachedTo());
} }

View File

@ -72,7 +72,7 @@ public class BooleanRoundInputConnector implements BooleanInputConnector {
@Override @Override
public void getAttachment(Wire<BooleanSignal, BooleanInputConnector> wire) { public void addAttachment(Wire<BooleanSignal, BooleanInputConnector> wire) {
_attachments.add(wire); _attachments.add(wire);
} }
@ -92,7 +92,7 @@ public class BooleanRoundInputConnector implements BooleanInputConnector {
} }
@Override @Override
public void unlinkWire(Wire wire) { public void wireUnlinked(Wire wire) {
_attachments.remove(wire); _attachments.remove(wire);
} }
} }

View File

@ -94,7 +94,7 @@ public class BooleanRoundOutputConnector implements Drawable, BooleanOutputConne
} }
@Override @Override
public void unlinkWire(BooleanWire wire) { public void wireUnlinked(BooleanWire wire) {
_wires.remove(wire); _wires.remove(wire);
_connections.remove(wire.getAttachedTo()); _connections.remove(wire.getAttachedTo());
} }

View File

@ -2,8 +2,12 @@ package com.codigoparallevar.minicards.parts.connectors;
import com.codigoparallevar.minicards.parts.style.CardTheme; import com.codigoparallevar.minicards.parts.style.CardTheme;
import org.json.JSONException;
import org.json.JSONObject;
public class ConnectorTypeInfo { public class ConnectorTypeInfo {
private final Type _type; private final Type _type;
private static final String SERIALIZED_TYPE_KEY = "type";
public static ConnectorTypeInfo FromTypeName(String type) { public static ConnectorTypeInfo FromTypeName(String type) {
if (type == null) { if (type == null) {
@ -37,6 +41,34 @@ public class ConnectorTypeInfo {
} }
} }
private static String typeToString(Type type) {
switch (type) {
case ANY:
return "any";
case ENUM:
return "enum";
case FLOAT:
return "float";
case PULSE:
return "pulse";
case STRING:
return "string";
case BOOLEAN:
return "boolean";
case INTEGER:
return "integer";
case UNKNOWN:
return "unknown";
default:
return "unknown";
}
}
public static ConnectorTypeInfo deserialize(JSONObject jsonTypeInfo) {
return ConnectorTypeInfo.FromTypeName(jsonTypeInfo.optString(SERIALIZED_TYPE_KEY));
}
public int getOuterColor() { public int getOuterColor() {
switch (_type) { switch (_type) {
case ANY: case ANY:
@ -84,6 +116,16 @@ public class ConnectorTypeInfo {
} }
} }
public JSONObject serialize() {
JSONObject obj = new JSONObject();
try {
obj.put(SERIALIZED_TYPE_KEY, ConnectorTypeInfo.typeToString(this._type));
} catch (JSONException e) {
e.printStackTrace();
}
return obj;
}
public enum Type { public enum Type {
PULSE, PULSE,
BOOLEAN, BOOLEAN,

View File

@ -2,9 +2,13 @@ package com.codigoparallevar.minicards.parts.connectors;
import android.util.Log; import android.util.Log;
import com.codigoparallevar.minicards.CanvasView;
import com.codigoparallevar.minicards.parts.values.StaticValuePart;
import com.codigoparallevar.minicards.types.Moveable; import com.codigoparallevar.minicards.types.Moveable;
import com.codigoparallevar.minicards.types.Part; import com.codigoparallevar.minicards.types.Part;
import com.codigoparallevar.minicards.types.PartGrid;
import com.codigoparallevar.minicards.types.connectors.RoundConnector; import com.codigoparallevar.minicards.types.connectors.RoundConnector;
import com.codigoparallevar.minicards.types.connectors.Wiring.AnyWire;
import com.codigoparallevar.minicards.types.connectors.Wiring.Wire; import com.codigoparallevar.minicards.types.connectors.Wiring.Wire;
import com.codigoparallevar.minicards.types.connectors.input.AnyInputConnector; import com.codigoparallevar.minicards.types.connectors.input.AnyInputConnector;
import com.codigoparallevar.minicards.types.wireData.AnySignal; import com.codigoparallevar.minicards.types.wireData.AnySignal;
@ -12,20 +16,25 @@ import com.codigoparallevar.minicards.types.wireData.AnySignal;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
public class AnyRoundInputConnector extends AnyInputConnector implements RoundConnector { public class ProgramakerCustomBlockInputConnector extends AnyInputConnector implements RoundConnector {
private static final int STATIC_VALUE_SEPARATION = 200;
private final Part _part; private final Part _part;
private final ConnectorTypeInfo _typeInfo;
private final PartGrid _partGrid;
private int _xposition; private int _xposition;
private int _yposition; private int _yposition;
private final int _radius; private final int _radius;
private final List<Wire> _attachments = new LinkedList<>(); private final List<Wire> _attachments = new LinkedList<>();
public AnyRoundInputConnector(Part part, public ProgramakerCustomBlockInputConnector(Part part, PartGrid partGrid,
int inputConnectorCenterX, int inputConnectorCenterY, int inputConnectorCenterX, int inputConnectorCenterY,
int inputConnectorRadius) { int inputConnectorRadius, ConnectorTypeInfo typeInfo) {
_part = part; _part = part;
_partGrid = partGrid;
_xposition = inputConnectorCenterX; _xposition = inputConnectorCenterX;
_yposition = inputConnectorCenterY; _yposition = inputConnectorCenterY;
_radius = inputConnectorRadius; _radius = inputConnectorRadius;
_typeInfo = typeInfo;
} }
@Override @Override
@ -86,9 +95,8 @@ public class AnyRoundInputConnector extends AnyInputConnector implements RoundCo
_part.send(this, signal); _part.send(this, signal);
} }
@Override @Override
public void getAttachment(Wire wire) { public void addAttachment(Wire wire) {
_attachments.add(wire); _attachments.add(wire);
} }
@ -108,7 +116,25 @@ public class AnyRoundInputConnector extends AnyInputConnector implements RoundCo
} }
@Override @Override
public void unlinkWire(Wire wire) { public void wireUnlinked(Wire wire) {
_attachments.remove(wire); _attachments.remove(wire);
} }
public void touched() {
// If it doesn't have wires connected, spawn a value block
if (this._attachments.size() > 0) {
return;
}
final PartGrid grid = _partGrid;
if (grid instanceof CanvasView) {
StaticValuePart value = new StaticValuePart(_partGrid,
this._xposition, this._yposition - STATIC_VALUE_SEPARATION,
this._typeInfo);
AnyWire wire = value.getOutputWire();
value.getValueOutput().drop(wire, this);
((CanvasView) grid).addPart(value);
}
}
} }

View File

@ -75,7 +75,7 @@ public class RoundInputConnector implements SignalInputConnector {
} }
@Override @Override
public void getAttachment(Wire<Signal, SignalInputConnector> wire) { public void addAttachment(Wire<Signal, SignalInputConnector> wire) {
_attachments.add(wire); _attachments.add(wire);
} }
@ -95,7 +95,7 @@ public class RoundInputConnector implements SignalInputConnector {
} }
@Override @Override
public void unlinkWire(Wire wire) { public void wireUnlinked(Wire wire) {
_attachments.remove(wire); _attachments.remove(wire);
} }
} }

View File

@ -97,7 +97,7 @@ public class SignalRoundOutputConnector implements Drawable, SignalOutputConnect
} }
@Override @Override
public void unlinkWire(SignalWire wire) { public void wireUnlinked(SignalWire wire) {
_wires.remove(wire); _wires.remove(wire);
_connections.remove(wire.getAttachedTo()); _connections.remove(wire.getAttachedTo());
} }

View File

@ -72,7 +72,7 @@ public class StringRoundInputConnector implements StringInputConnector {
@Override @Override
public void getAttachment(Wire<StringSignal, StringInputConnector> wire) { public void addAttachment(Wire<StringSignal, StringInputConnector> wire) {
_attachments.add(wire); _attachments.add(wire);
} }
@ -92,7 +92,7 @@ public class StringRoundInputConnector implements StringInputConnector {
} }
@Override @Override
public void unlinkWire(Wire wire) { public void wireUnlinked(Wire wire) {
_attachments.remove(wire); _attachments.remove(wire);
} }
} }

View File

@ -7,11 +7,12 @@ import com.codigoparallevar.minicards.types.Drawable;
import com.codigoparallevar.minicards.types.Moveable; import com.codigoparallevar.minicards.types.Moveable;
import com.codigoparallevar.minicards.types.Part; import com.codigoparallevar.minicards.types.Part;
import com.codigoparallevar.minicards.types.PartGrid; import com.codigoparallevar.minicards.types.PartGrid;
import com.codigoparallevar.minicards.types.functional.Tuple2;
import com.codigoparallevar.minicards.types.connectors.Wiring.StringWire; import com.codigoparallevar.minicards.types.connectors.Wiring.StringWire;
import com.codigoparallevar.minicards.types.connectors.Wiring.Wire;
import com.codigoparallevar.minicards.types.connectors.input.InputConnector; import com.codigoparallevar.minicards.types.connectors.input.InputConnector;
import com.codigoparallevar.minicards.types.connectors.input.StringInputConnector; import com.codigoparallevar.minicards.types.connectors.input.StringInputConnector;
import com.codigoparallevar.minicards.types.connectors.output.StringOutputConnector; import com.codigoparallevar.minicards.types.connectors.output.StringOutputConnector;
import com.codigoparallevar.minicards.types.functional.Tuple2;
import com.codigoparallevar.minicards.types.wireData.StringSignal; import com.codigoparallevar.minicards.types.wireData.StringSignal;
import java.util.HashSet; import java.util.HashSet;
@ -94,7 +95,7 @@ public class StringRoundOutputConnector implements Drawable, StringOutputConnect
} }
@Override @Override
public void unlinkWire(StringWire wire) { public void wireUnlinked(StringWire wire) {
_wires.remove(wire); _wires.remove(wire);
_connections.remove(wire.getAttachedTo()); _connections.remove(wire.getAttachedTo());
} }

View File

@ -7,7 +7,8 @@ import android.util.Log;
import com.codigoparallevar.minicards.PartInstantiator; import com.codigoparallevar.minicards.PartInstantiator;
import com.codigoparallevar.minicards.ScrolledCanvas; import com.codigoparallevar.minicards.ScrolledCanvas;
import com.codigoparallevar.minicards.parts.connectors.AnyRoundInputConnector; import com.codigoparallevar.minicards.parts.connectors.ConnectorTypeInfo;
import com.codigoparallevar.minicards.parts.connectors.ProgramakerCustomBlockInputConnector;
import com.codigoparallevar.minicards.parts.connectors.StringRoundOutputConnector; import com.codigoparallevar.minicards.parts.connectors.StringRoundOutputConnector;
import com.codigoparallevar.minicards.parts.style.CardTheme; import com.codigoparallevar.minicards.parts.style.CardTheme;
import com.codigoparallevar.minicards.types.Moveable; import com.codigoparallevar.minicards.types.Moveable;
@ -56,11 +57,12 @@ public class ConvertToString implements Part {
_lastValue = null; _lastValue = null;
// Input connector // Input connector
_toggleInputConnector = new AnyRoundInputConnector( ConnectorTypeInfo typeInfo = new ConnectorTypeInfo(ConnectorTypeInfo.Type.ANY);
this, _toggleInputConnector = new ProgramakerCustomBlockInputConnector(
this, _partGrid,
getInputConnectorCenterX(), getInputConnectorCenterX(),
getInputConnectorCenterY(), getInputConnectorCenterY(),
getInputConnectRadius()); getInputConnectRadius(), typeInfo);
inputConnectors = new LinkedList<>(); inputConnectors = new LinkedList<>();
inputConnectors.add(_toggleInputConnector); inputConnectors.add(_toggleInputConnector);

View File

@ -0,0 +1,406 @@
package com.codigoparallevar.minicards.parts.values;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.text.InputType;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import com.codigoparallevar.minicards.R;
import com.codigoparallevar.minicards.ScrolledCanvas;
import com.codigoparallevar.minicards.parts.connectors.AnyRoundOutputConnector;
import com.codigoparallevar.minicards.parts.connectors.ConnectorTypeInfo;
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.connectors.Wiring.AnyWire;
import com.codigoparallevar.minicards.types.connectors.input.InputConnector;
import com.codigoparallevar.minicards.types.connectors.output.OutputConnector;
import com.codigoparallevar.minicards.types.functional.Tuple2;
import com.codigoparallevar.minicards.types.wireData.WireDataType;
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.UUID;
public class StaticValuePart implements Part {
private static final int WIDTH_PADDING = 25;
private static final int HEIGHT_PADDING = 25;
private static final int MIN_HEIGHT = 100;
private static final int MIN_WIDTH = 100;
private static final String LogTag = "PM StaticValue";
private static final int IO_RADIUS = 50;
private static final int IO_PADDING = 20;
private final String _id;
private final AnyRoundOutputConnector _outputConnector;
private final ConnectorTypeInfo _typeInfo;
private final PartGrid _grid;
private int _width;
private int _height;
private int _left;
private int _top;
private String _value = null;
public StaticValuePart(String id, PartGrid grid, int centerx, int centery, ConnectorTypeInfo typeInfo, String value) {
this._id = id;
this._typeInfo = typeInfo;
this._grid = grid;
this._value = value;
this.updateWidthHeight();
this._left = centerx - this._width / 2;
this._top = centery - this._height / 2;
this._outputConnector = new AnyRoundOutputConnector(this, grid,
this._left + _width / 2,
this._top + _height, IO_RADIUS);
}
public StaticValuePart(String id, PartGrid grid, int centerx, int centery, ConnectorTypeInfo typeInfo) {
this(id, grid, centerx, centery, typeInfo, null);
}
public StaticValuePart(PartGrid grid, int centerx, int centery, ConnectorTypeInfo typeInfo) {
this(UUID.randomUUID().toString(), grid, centerx, centery, typeInfo);
}
@Override
public JSONObject serialize() throws JSONException {
JSONObject serialized = new JSONObject();
serialized.put("id", _id);
serialized.put("left", _left);
serialized.put("top", _top);
serialized.put("value", _value == null ? JSONObject.NULL : _value);
JSONObject jsonTypeInfo = _typeInfo.serialize();
serialized.put("type_info", jsonTypeInfo);
serialized.put("on_string_output_connector", serializeConnectionEndpoints());
return serialized;
}
private JSONArray serializeConnectionEndpoints() {
JSONArray serializedData = new JSONArray();
for (OutputConnector output : getOutputConnectors()) {
JSONArray elements = new JSONArray();
for (Tuple2<String, String> endpoint : (List<Tuple2<String, String>>) output.getConnectionEndpoints()) {
elements.put(PartConnection.serializeToJson(endpoint.item1, endpoint.item2));
}
serializedData.put(elements);
}
return serializedData;
}
public static Tuple2<Part, List<PartConnection>> deserialize(PartGrid grid, JSONObject data) throws JSONException {
String id = data.getString("id");
int left = data.getInt("left");
int top = data.getInt("top");
String value = data.optString("value");
JSONObject jsonTypeInfo = data.getJSONObject("type_info");
ConnectorTypeInfo typeInfo = ConnectorTypeInfo.deserialize(jsonTypeInfo);
StaticValuePart part = new StaticValuePart(id, grid, left, top, typeInfo, value);
List<PartConnection> connections = new LinkedList<>();
JSONArray allConnectorOuts = data.optJSONArray("on_string_output_connector");
if (allConnectorOuts == null) {
allConnectorOuts = new JSONArray();
}
for (int i = 0; i < allConnectorOuts.length(); i++) {
JSONArray connectorOuts = allConnectorOuts.getJSONArray(i);
OutputConnector connector = part.getOutputConnectors().get(i);
for (int j = 0; j < connectorOuts.length(); j++) {
connections.add(PartConnection.deserialize(
connector, connectorOuts.getJSONObject(j)));
}
}
return new Tuple2<>(part, connections);
}
public AnyWire getOutputWire() {
return this._outputConnector.getMoveable();
}
@Override
public int get_left() {
return _left;
}
@Override
public int get_right() {
return _left + _width;
}
@Override
public int get_top() {
return _top;
}
@Override
public int get_bottom() {
return _top + _height;
}
private void updateWidthHeight() {
Paint p = getTextPaint();
String message = getMessage();
Rect bounds = new Rect();
p.getTextBounds(message, 0, message.length(), bounds);
this._height = Math.max(MIN_HEIGHT, bounds.height() + HEIGHT_PADDING * 2);
int newWidth = Math.max(MIN_WIDTH, bounds.width() + WIDTH_PADDING * 2);
if (this._width > 0) { // Re-center block
this._left -= (newWidth - _width) / 2;
}
this._width = newWidth;
}
private String getMessage() {
ConnectorTypeInfo.Type type = _typeInfo.get_type();
if (type == ConnectorTypeInfo.Type.INTEGER || type == ConnectorTypeInfo.Type.FLOAT) {
if (_value == null) {
return "0";
}
try {
Integer.parseInt(_value);
return _value;
} catch(NumberFormatException ex) {
Log.w(LogTag, "StaticPart (type=number), value found=" + _value, ex);
return "0";
}
}
else {
if (_value == null) {
return "-";
} else {
return _value;
}
}
}
private Paint getTextPaint() {
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
p.setColor(Color.BLACK);
p.setTextSize(50);
return p;
}
@Override
public void touched() {
if (!(this._grid instanceof View)) {
return; // Can't show dialog if can't retrieve context
}
ConnectorTypeInfo.Type type = this._typeInfo.get_type();
if (type == ConnectorTypeInfo.Type.PULSE) {
return; // Nothing to do here
}
Context ctx = ((View) this._grid).getContext();
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
builder.setTitle(R.string.set_value);
Runnable prepareOnAccept = () -> {};
switch (type) {
case BOOLEAN:
break;
case INTEGER:
case FLOAT:
{
final EditText input = new EditText(ctx);
input.setText(getMessage());
input.setInputType(InputType.TYPE_CLASS_NUMBER);
builder.setView(input);
prepareOnAccept = () -> {
_value = input.getText().toString();
};
break;
}
default:
case ENUM:
// TODO: Show enumerated values
case ANY:
case UNKNOWN:
case STRING:
{
final EditText input = new EditText(ctx);
input.setText(getMessage());
input.setInputType(InputType.TYPE_CLASS_TEXT);
builder.setView(input);
prepareOnAccept = () -> {
_value = input.getText().toString();
};
break;
}
}
final Runnable onAccept = prepareOnAccept;
builder
.setPositiveButton(R.string.ok_accept_changes, (dialog, which) -> {
onAccept.run();
this.updateWidthHeight();
((View) this._grid).invalidate();
})
.setNegativeButton(R.string.cancel_discard_changes, (dialog, which) -> {
// No change
} );
AlertDialog dialog = builder.create();
dialog.show();
}
@Override
public List<InputConnector> getInputConnectors() {
// There is not going to be one
return Collections.emptyList();
}
@Override
public List<OutputConnector> getOutputConnectors() {
return new LinkedList<OutputConnector>() {{
add(_outputConnector);
}};
}
public AnyRoundOutputConnector getValueOutput() {
return _outputConnector;
}
@Override
public void send(InputConnector inputConnector, WireDataType signal) {
}
@Override
public String get_id() {
return _id;
}
@Override
public InputConnector getConnectorWithId(String inputConnectorId) {
return null; // No inputs
}
@Override
public String getConnectorId(InputConnector inputConnector) {
return null; // No inputs
}
@Override
public void resume() {
// Nothing to do
}
@Override
public void pause() {
// Nothing to do
}
@Override
public Object query(Object lastValue) {
return this._value;
}
@Override
public void draw(ScrolledCanvas canvas, boolean devMode) {
this.updateWidthHeight(); // TODO: Remove after calculations stabilize
if (!devMode) {
return; // Logic block, don't show on user-mode
}
drawConnectors(canvas);
drawWires(canvas, devMode);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.parseColor("#E3FCFC"));
canvas.drawRect(
new Rect(get_left(), get_top(),
get_right(), get_bottom()),
paint);
Paint textPaint = getTextPaint();
canvas.drawText(getMessage(),
get_left() + WIDTH_PADDING,
get_bottom() - HEIGHT_PADDING,
textPaint);
}
private void drawConnectors(ScrolledCanvas canvas) {
Paint outerOutputConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
outerOutputConnectorPaint.setColor(_typeInfo.getOuterColor());
canvas.drawCircle(
_outputConnector.getX(),
_outputConnector.getY(),
_outputConnector.getRadius(),
outerOutputConnectorPaint);
Paint innerOutputConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
innerOutputConnectorPaint.setColor(_typeInfo.getInnerColor());
canvas.drawCircle(
_outputConnector.getX(),
_outputConnector.getY(),
_outputConnector.getRadius() / 2,
innerOutputConnectorPaint);
}
private void drawWires(ScrolledCanvas canvas, boolean devMode) {
_outputConnector.drawWires(canvas, devMode);
}
@Override
public void moveEnd(int x, int y) {
_left = x - _width / 2;
_top = y - _height / 2;
this._outputConnector.updatePosition(
this._left + _width / 2,
this._top + _height);
}
@Override
public void drop(int x, int y) {
moveEnd(x, y);
}
@Override
public boolean containsPoint(int x, int y) {
return ((x >= this.get_left()) && (x <= this.get_right())
&& (y >= this.get_top()) && (y <= this.get_bottom()));
}
@Override
public Moveable getMoveable() {
return this;
}
@Override
public void unlink() {
// Nothing to do
_outputConnector.unlink();
}
}

View File

@ -4,5 +4,5 @@ import com.codigoparallevar.minicards.types.connectors.Wiring.Wire;
public interface Dropper<T extends Wire> { public interface Dropper<T extends Wire> {
void drop(T wire); void drop(T wire);
void unlinkWire(T wire); void wireUnlinked(T wire);
} }

View File

@ -4,6 +4,7 @@ import com.codigoparallevar.minicards.types.connectors.input.InputConnector;
import com.codigoparallevar.minicards.types.connectors.output.OutputConnector; import com.codigoparallevar.minicards.types.connectors.output.OutputConnector;
import com.codigoparallevar.minicards.types.wireData.WireDataType; import com.codigoparallevar.minicards.types.wireData.WireDataType;
import org.jetbrains.annotations.NotNull;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@ -20,6 +21,7 @@ public interface Part extends Selectable, Moveable, Drawable {
List<InputConnector> getInputConnectors(); List<InputConnector> getInputConnectors();
List<OutputConnector> getOutputConnectors(); List<OutputConnector> getOutputConnectors();
@NotNull
JSONObject serialize() throws JSONException; JSONObject serialize() throws JSONException;
void send(InputConnector inputConnector, WireDataType signal); void send(InputConnector inputConnector, WireDataType signal);

View File

@ -83,7 +83,7 @@ public class Wire<T extends WireDataType, InputConnectorType extends InputConnec
_xend = resultPoint.getX(); _xend = resultPoint.getX();
_yend = resultPoint.getY(); _yend = resultPoint.getY();
resultPoint.getAttachment(this); resultPoint.addAttachment(this);
invalidatePath(); invalidatePath();
} }
@ -98,8 +98,8 @@ public class Wire<T extends WireDataType, InputConnectorType extends InputConnec
} }
public void unlink() { public void unlink() {
_attachedFrom.unlinkWire(this); _attachedFrom.wireUnlinked(this);
_attachedTo.unlinkWire(this); _attachedTo.wireUnlinked(this);
} }
public Object query(Object lastValue) { public Object query(Object lastValue) {

View File

@ -100,8 +100,8 @@ public abstract class AnyInputConnector implements InputConnector<AnySignal, Any
baseInputConnector.drop(wire); baseInputConnector.drop(wire);
} }
public void unlinkWire(Wire wire) { public void wireUnlinked(Wire wire) {
baseInputConnector.unlinkWire(wire); baseInputConnector.wireUnlinked(wire);
} }
public void updatePosition(int x, int y) { public void updatePosition(int x, int y) {
@ -124,8 +124,8 @@ public abstract class AnyInputConnector implements InputConnector<AnySignal, Any
return baseInputConnector.getId(); return baseInputConnector.getId();
} }
public void getAttachment(Wire wire) { public void addAttachment(Wire wire) {
baseInputConnector.getAttachment(wire); baseInputConnector.addAttachment(wire);
} }
} }
} }

View File

@ -12,13 +12,16 @@ public interface InputConnector<T extends WireDataType, T1 extends InputConnecto
void updatePosition(int x, int y); void updatePosition(int x, int y);
int getX(); int getX();
int getY(); int getY();
void getAttachment(Wire<T, T1> wire); void addAttachment(Wire<T, T1> wire);
Part getPart(); Part getPart();
String getId(); String getId();
void send(T data); void send(T data);
void wireUnlinked(Wire wire);
} }

View File

@ -1,5 +1,6 @@
package com.codigoparallevar.minicards.types.connectors.input; package com.codigoparallevar.minicards.types.connectors.input;
import com.codigoparallevar.minicards.types.connectors.Wiring.SignalWire;
import com.codigoparallevar.minicards.types.wireData.Signal; import com.codigoparallevar.minicards.types.wireData.Signal;
public interface SignalInputConnector extends InputConnector<Signal, SignalInputConnector> { public interface SignalInputConnector extends InputConnector<Signal, SignalInputConnector> {

View File

@ -27,4 +27,6 @@ public interface OutputConnector<T extends WireDataType,
Object query(Object lastValue); Object query(Object lastValue);
List<T2> getWires(); List<T2> getWires();
void wireUnlinked(T2 wire);
} }

View File

@ -26,4 +26,7 @@
<string name="stop_bridge">Stop bridge</string> <string name="stop_bridge">Stop bridge</string>
<string name="start_bridge">Start bridge</string> <string name="start_bridge">Start bridge</string>
<string name="vibration_activated">Vibration activated</string> <string name="vibration_activated">Vibration activated</string>
<string name="set_value">Set block value</string>
<string name="ok_accept_changes">OK</string>
<string name="cancel_discard_changes">Cancel</string>
</resources> </resources>