Draw all block parameters, call bridge when activated.
This commit is contained in:
parent
de2d474294
commit
2c88dd4b03
@ -4,27 +4,29 @@ import android.content.Context;
|
|||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.codigoparallevar.minicards.motion.MotionMode;
|
import com.codigoparallevar.minicards.motion.MotionMode;
|
||||||
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;
|
||||||
import com.codigoparallevar.minicards.types.Position;
|
import com.codigoparallevar.minicards.types.Position;
|
||||||
import com.codigoparallevar.minicards.types.Selectable;
|
import com.codigoparallevar.minicards.types.Selectable;
|
||||||
import com.codigoparallevar.minicards.types.functional.Tuple2;
|
|
||||||
import com.codigoparallevar.minicards.types.functional.Tuple4;
|
|
||||||
import com.codigoparallevar.minicards.types.connectors.input.AnyInputConnector;
|
import com.codigoparallevar.minicards.types.connectors.input.AnyInputConnector;
|
||||||
import com.codigoparallevar.minicards.types.connectors.input.BooleanInputConnector;
|
import com.codigoparallevar.minicards.types.connectors.input.BooleanInputConnector;
|
||||||
import com.codigoparallevar.minicards.types.connectors.input.InputConnector;
|
import com.codigoparallevar.minicards.types.connectors.input.InputConnector;
|
||||||
import com.codigoparallevar.minicards.types.connectors.input.SignalInputConnector;
|
import com.codigoparallevar.minicards.types.connectors.input.SignalInputConnector;
|
||||||
import com.codigoparallevar.minicards.types.connectors.input.StringInputConnector;
|
import com.codigoparallevar.minicards.types.connectors.input.StringInputConnector;
|
||||||
import com.codigoparallevar.minicards.types.connectors.output.OutputConnector;
|
import com.codigoparallevar.minicards.types.connectors.output.OutputConnector;
|
||||||
|
import com.codigoparallevar.minicards.types.functional.Tuple2;
|
||||||
|
import com.codigoparallevar.minicards.types.functional.Tuple4;
|
||||||
|
import com.programaker.api.ProgramakerApi;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -51,6 +53,7 @@ public class CanvasView extends View implements PartGrid {
|
|||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private String name = "default";
|
private String name = "default";
|
||||||
|
private ProgramakerApi api = null;
|
||||||
private final static float touchTimeForLongTouchInMillis = 500;
|
private final static float touchTimeForLongTouchInMillis = 500;
|
||||||
private boolean _isDragging = false;
|
private boolean _isDragging = false;
|
||||||
private CardActivity parentActivity = null;
|
private CardActivity parentActivity = null;
|
||||||
@ -142,7 +145,7 @@ public class CanvasView extends View implements PartGrid {
|
|||||||
part.draw(scrolledCanvas, _devMode);
|
part.draw(scrolledCanvas, _devMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d("Render time", System.currentTimeMillis() - renderStartTime + "ms");
|
// Log.d("Render time", System.currentTimeMillis() - renderStartTime + "ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void drawBackground(ScrolledCanvas canvas) {
|
private void drawBackground(ScrolledCanvas canvas) {
|
||||||
@ -236,6 +239,7 @@ public class CanvasView extends View implements PartGrid {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.d("CanvasView", "Moving part="+selectedPart);
|
||||||
if (selectedPart == null){
|
if (selectedPart == null){
|
||||||
int xMovement = _mouseDownPoint.item1 - xInScreen;
|
int xMovement = _mouseDownPoint.item1 - xInScreen;
|
||||||
int yMovement = _mouseDownPoint.item2 - yInScreen;
|
int yMovement = _mouseDownPoint.item2 - yInScreen;
|
||||||
@ -323,22 +327,38 @@ public class CanvasView extends View implements PartGrid {
|
|||||||
for (int i = parts.size() - 1; i >= 0; i--){
|
for (int i = parts.size() - 1; i >= 0; i--){
|
||||||
final Part part = parts.get(i);
|
final Part part = parts.get(i);
|
||||||
// First try with output connectors
|
// First try with output connectors
|
||||||
for (OutputConnector outputConnector : part.getOutputConnectors()){
|
List<OutputConnector> outputConnectors = part.getOutputConnectors();
|
||||||
|
if (outputConnectors != null) {
|
||||||
|
for (OutputConnector outputConnector : outputConnectors) {
|
||||||
if (outputConnector.containsPoint(x, y)) {
|
if (outputConnector.containsPoint(x, y)) {
|
||||||
return outputConnector;
|
return outputConnector;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Then with input ones
|
// Then with input ones
|
||||||
for (InputConnector inputConnector : part.getInputConnectors()){
|
List<InputConnector> inputConnectors = part.getInputConnectors();
|
||||||
|
if (inputConnectors != null) {
|
||||||
|
for (InputConnector inputConnector : inputConnectors) {
|
||||||
if (inputConnector.containsPoint(x, y)) {
|
if (inputConnector.containsPoint(x, y)) {
|
||||||
return inputConnector;
|
return inputConnector;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProgramakerApi getApi() {
|
||||||
|
if (api == null) {
|
||||||
|
api = new ProgramakerApi();
|
||||||
|
api.setToken(new ConfigManager(this.getContext()).getToken());
|
||||||
|
}
|
||||||
|
return api;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public SignalInputConnector getSignalInputConnectorOn(int x, int y) {
|
public SignalInputConnector getSignalInputConnectorOn(int x, int y) {
|
||||||
|
@ -2,6 +2,14 @@ package com.codigoparallevar.minicards;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.ActionBar;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
import com.codigoparallevar.minicards.toolbox.PartsHolder;
|
import com.codigoparallevar.minicards.toolbox.PartsHolder;
|
||||||
import com.codigoparallevar.minicards.types.functional.Consumer;
|
import com.codigoparallevar.minicards.types.functional.Consumer;
|
||||||
@ -15,15 +23,6 @@ import com.programaker.api.data.ProgramakerBridgeInfo;
|
|||||||
import com.programaker.api.data.api_results.ProgramakerBridgeCustomBlockResult;
|
import com.programaker.api.data.api_results.ProgramakerBridgeCustomBlockResult;
|
||||||
import com.programaker.api.data.api_results.ProgramakerGetCustomBlocksResult;
|
import com.programaker.api.data.api_results.ProgramakerGetCustomBlocksResult;
|
||||||
|
|
||||||
import androidx.appcompat.app.ActionBar;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
|
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -146,8 +145,7 @@ public class CardActivity extends AppCompatActivity {
|
|||||||
ShowDeckFromDevModeButton.setOnClickListener(new View.OnClickListener() {
|
ShowDeckFromDevModeButton.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
Intent i = new Intent(DeckPreviewActivity.INTENT);
|
finish();
|
||||||
CardActivity.this.startActivity(i);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -156,8 +154,7 @@ public class CardActivity extends AppCompatActivity {
|
|||||||
ShowDeckFromUserModeButton.setOnClickListener(new View.OnClickListener() {
|
ShowDeckFromUserModeButton.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
Intent i = new Intent(DeckPreviewActivity.INTENT);
|
finish();
|
||||||
CardActivity.this.startActivity(i);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -4,9 +4,11 @@ import android.annotation.TargetApi;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import com.codigoparallevar.minicards.parts.ProgramakerCustomBlockPart;
|
||||||
import com.codigoparallevar.minicards.parts.buttons.RoundButton;
|
import com.codigoparallevar.minicards.parts.buttons.RoundButton;
|
||||||
import com.codigoparallevar.minicards.parts.logic.Ticker;
|
import com.codigoparallevar.minicards.parts.logic.Ticker;
|
||||||
import com.codigoparallevar.minicards.parts.logic.Toggle;
|
import com.codigoparallevar.minicards.parts.logic.Toggle;
|
||||||
@ -284,6 +286,13 @@ public class CardFile {
|
|||||||
|
|
||||||
return convertToStringInfo;
|
return convertToStringInfo;
|
||||||
}
|
}
|
||||||
|
else if (type.equals(ProgramakerCustomBlockPart.class.getName())){
|
||||||
|
Tuple2<Part, List<PartConnection>> customBlockPartInfo = ProgramakerCustomBlockPart.deserialize(
|
||||||
|
grid,
|
||||||
|
jsonObject.getJSONObject("_data"));
|
||||||
|
|
||||||
|
return customBlockPartInfo;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
throw new JSONException("Expected known class, found " + type);
|
throw new JSONException("Expected known class, found " + type);
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import com.codigoparallevar.minicards.types.functional.Tuple2;
|
|||||||
import com.codigoparallevar.minicards.types.connectors.input.BooleanInputConnector;
|
import com.codigoparallevar.minicards.types.connectors.input.BooleanInputConnector;
|
||||||
import com.codigoparallevar.minicards.types.connectors.input.SignalInputConnector;
|
import com.codigoparallevar.minicards.types.connectors.input.SignalInputConnector;
|
||||||
import com.codigoparallevar.minicards.types.connectors.input.StringInputConnector;
|
import com.codigoparallevar.minicards.types.connectors.input.StringInputConnector;
|
||||||
|
import com.programaker.api.ProgramakerApi;
|
||||||
|
|
||||||
class StubPartGrid implements PartGrid {
|
class StubPartGrid implements PartGrid {
|
||||||
@Override
|
@Override
|
||||||
@ -13,6 +14,11 @@ class StubPartGrid implements PartGrid {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProgramakerApi getApi() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SignalInputConnector getSignalInputConnectorOn(int x, int y) {
|
public SignalInputConnector getSignalInputConnectorOn(int x, int y) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -1,38 +1,82 @@
|
|||||||
package com.codigoparallevar.minicards.parts;
|
package com.codigoparallevar.minicards.parts;
|
||||||
|
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
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.ConnectorTypeInfo;
|
||||||
|
import com.codigoparallevar.minicards.parts.connectors.RoundOutputConnector;
|
||||||
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.PartConnection;
|
||||||
import com.codigoparallevar.minicards.types.PartGrid;
|
import com.codigoparallevar.minicards.types.PartGrid;
|
||||||
import com.codigoparallevar.minicards.types.connectors.input.InputConnector;
|
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.functional.Tuple2;
|
import com.codigoparallevar.minicards.types.functional.Tuple2;
|
||||||
import com.codigoparallevar.minicards.types.wireData.WireDataType;
|
import com.codigoparallevar.minicards.types.wireData.WireDataType;
|
||||||
|
import com.codigoparallevar.minicards.ui_helpers.DoAsync;
|
||||||
|
import com.programaker.api.ProgramakerApi;
|
||||||
import com.programaker.api.data.ProgramakerCustomBlock;
|
import com.programaker.api.data.ProgramakerCustomBlock;
|
||||||
|
import com.programaker.api.data.ProgramakerCustomBlockArgument;
|
||||||
|
import com.programaker.api.data.ProgramakerCustomBlockSaveTo;
|
||||||
|
import com.programaker.api.data.ProgramakerFunctionCallResult;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class ProgramakerCustomBlockPart implements Part {
|
public class ProgramakerCustomBlockPart implements Part {
|
||||||
|
private static final int WIDTH_PADDING = 50;
|
||||||
|
private static final int HEIGHT_PADDING = 50;
|
||||||
|
private static final int IO_RADIUS = 50;
|
||||||
|
private static final int IO_PADDING = 20;
|
||||||
|
private static final String LogTag = "PM Custom block part";
|
||||||
|
|
||||||
|
private List<Tuple2<ConnectorTypeInfo, AnyRoundInputConnector>> inputConnectors = null;
|
||||||
|
private List<Tuple2<ConnectorTypeInfo, RoundOutputConnector>> outputConnectors = null;
|
||||||
|
|
||||||
private final PartGrid _partGrid;
|
private final PartGrid _partGrid;
|
||||||
private final String _id;
|
private final String _id;
|
||||||
private int _xCenter;
|
|
||||||
private int _yCenter;
|
|
||||||
private final ProgramakerCustomBlock _block;
|
private final ProgramakerCustomBlock _block;
|
||||||
|
|
||||||
|
private int _left;
|
||||||
|
private int _top;
|
||||||
|
private int width = 100;
|
||||||
|
private int height = 100;
|
||||||
|
private String token = null;
|
||||||
|
private Object[] lastValues;
|
||||||
|
|
||||||
|
|
||||||
public ProgramakerCustomBlockPart(String id, PartGrid grid, Tuple2<Integer, Integer> center, ProgramakerCustomBlock block) {
|
public ProgramakerCustomBlockPart(String id, PartGrid grid, Tuple2<Integer, Integer> center, ProgramakerCustomBlock block) {
|
||||||
this._id = id;
|
this._id = id;
|
||||||
this._partGrid = grid;
|
this._partGrid = grid;
|
||||||
this._xCenter = center.item1;
|
|
||||||
this._yCenter = center.item2;
|
|
||||||
this._block = block;
|
this._block = block;
|
||||||
|
|
||||||
|
this.updateWidthHeight();
|
||||||
|
|
||||||
|
this._left = center.item1 - width / 2;
|
||||||
|
this._top = center.item2 - height / 2;
|
||||||
|
this.initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ProgramakerCustomBlockPart(String id, PartGrid grid, int left, int top, ProgramakerCustomBlock block) {
|
||||||
|
this._id = id;
|
||||||
|
this._partGrid = grid;
|
||||||
|
this._block = block;
|
||||||
|
|
||||||
|
this.updateWidthHeight();
|
||||||
|
|
||||||
|
this._left = left;
|
||||||
|
this._top = top;
|
||||||
|
this.initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProgramakerCustomBlockPart(PartGrid grid, Tuple2<Integer, Integer> center, ProgramakerCustomBlock block) {
|
public ProgramakerCustomBlockPart(PartGrid grid, Tuple2<Integer, Integer> center, ProgramakerCustomBlock block) {
|
||||||
@ -41,49 +85,296 @@ public class ProgramakerCustomBlockPart implements Part {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int get_left() {
|
public int get_left() {
|
||||||
return 0; // TODO: Implement
|
return _left;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int get_right() {
|
public int get_right() {
|
||||||
return 0; // TODO: Implement
|
return _left + width;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int get_top() {
|
public int get_top() {
|
||||||
return 0; // TODO: Implement
|
return _top;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int get_bottom() {
|
public int get_bottom() {
|
||||||
return 0; // TODO: Implement
|
return _top + height;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Paint getTextPaint() {
|
||||||
|
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
p.setColor(Color.BLACK);
|
||||||
|
p.setTextSize(50);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateWidthHeight() {
|
||||||
|
Paint p = getTextPaint();
|
||||||
|
String message = getMessage();
|
||||||
|
Rect bounds = new Rect();
|
||||||
|
p.getTextBounds(message, 0, message.length(), bounds);
|
||||||
|
|
||||||
|
this.height = bounds.height() + HEIGHT_PADDING * 2;
|
||||||
|
this.width = bounds.width() + WIDTH_PADDING * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initialize() {
|
||||||
|
this.updatePorts();
|
||||||
|
lastValues = new Object[this.inputConnectors.size()];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updatePorts() {
|
||||||
|
String type = this._block.getBlock_type() == null ? "" : this._block.getBlock_type();
|
||||||
|
boolean has_pulse_input = type.equals("operation");
|
||||||
|
boolean has_pulse_output = has_pulse_input || type.equals("trigger");
|
||||||
|
boolean hasImplicitOutput = type.equals("getter");
|
||||||
|
|
||||||
|
List<Tuple2<ConnectorTypeInfo, AnyRoundInputConnector>> inputs = new LinkedList<>();
|
||||||
|
List<Tuple2<ConnectorTypeInfo, RoundOutputConnector>> outputs = new LinkedList<>();
|
||||||
|
|
||||||
|
// Add pulses
|
||||||
|
if (has_pulse_input) {
|
||||||
|
inputs.add(new Tuple2<>(new ConnectorTypeInfo(ConnectorTypeInfo.Type.PULSE),
|
||||||
|
new AnyRoundInputConnector(this, 0, 0,
|
||||||
|
IO_RADIUS))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (has_pulse_output) {
|
||||||
|
outputs.add(new Tuple2<>(new ConnectorTypeInfo(ConnectorTypeInfo.Type.PULSE),
|
||||||
|
new RoundOutputConnector(this, this._partGrid, 0, 0,
|
||||||
|
IO_RADIUS))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add block IO
|
||||||
|
ProgramakerCustomBlockArgument savedTo = null;
|
||||||
|
|
||||||
|
if (_block.getArguments() != null) {
|
||||||
|
ProgramakerCustomBlockSaveTo saveTo = _block.getSave_to();
|
||||||
|
int skip = -1;
|
||||||
|
|
||||||
|
if (saveTo != null) {
|
||||||
|
if (saveTo.getType() != null
|
||||||
|
&& saveTo.getType().equals("argument")) {
|
||||||
|
skip = saveTo.getIndex();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Log.w(LogTag, "Unknown save-to type=" + saveTo.getType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = -1;
|
||||||
|
for (ProgramakerCustomBlockArgument arg : _block.getArguments()) {
|
||||||
|
index++;
|
||||||
|
if (skip == index) {
|
||||||
|
savedTo = arg;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
inputs.add(new Tuple2<>(ConnectorTypeInfo.FromTypeName(arg.getType()),
|
||||||
|
new AnyRoundInputConnector(this, 0, 0, IO_RADIUS)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (savedTo != null) {
|
||||||
|
outputs.add(new Tuple2<>(ConnectorTypeInfo.FromTypeName(savedTo.getType()),
|
||||||
|
new RoundOutputConnector(this, this._partGrid, 0, 0, IO_RADIUS)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasImplicitOutput) {
|
||||||
|
outputs.add(new Tuple2<>(ConnectorTypeInfo.FromTypeName(_block.getBlock_result_type()),
|
||||||
|
new RoundOutputConnector(this, this._partGrid, 0, 0, IO_RADIUS)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tie everything
|
||||||
|
inputConnectors = inputs;
|
||||||
|
outputConnectors = outputs;
|
||||||
|
|
||||||
|
this.updatePortPositions();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updatePortPositions() {
|
||||||
|
{
|
||||||
|
// Update inputs
|
||||||
|
int y = get_top();
|
||||||
|
int x = get_left() + IO_PADDING;
|
||||||
|
for (Tuple2<ConnectorTypeInfo, AnyRoundInputConnector> entry : inputConnectors) {
|
||||||
|
InputConnector input = entry.item2;
|
||||||
|
int new_x = x + IO_PADDING + IO_RADIUS / 2;
|
||||||
|
input.updatePosition(new_x, y);
|
||||||
|
x = x + IO_RADIUS * 2 + IO_PADDING * 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// Update outputs
|
||||||
|
int y = get_bottom();
|
||||||
|
int x = get_left() + IO_PADDING;
|
||||||
|
for (Tuple2<ConnectorTypeInfo, RoundOutputConnector> entry : outputConnectors) {
|
||||||
|
OutputConnector output = entry.item2;
|
||||||
|
int new_x = x + IO_PADDING + IO_RADIUS / 2;
|
||||||
|
output.updatePosition(new_x, y);
|
||||||
|
x = x + IO_RADIUS * 2 + IO_PADDING * 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getMessage() {
|
||||||
|
return this._block.getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void touched() {
|
public void touched() {
|
||||||
Log.i("CustomBlockPart", "Part touched (block_fun=" + this._block.getFunction_name() + ")");
|
Log.i(LogTag, "Part touched (block_fun=" + this._block.getFunction_name() + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<InputConnector> getInputConnectors() {
|
public List<InputConnector> getInputConnectors() {
|
||||||
return null;
|
List<InputConnector> result = new ArrayList<>(inputConnectors.size());
|
||||||
|
for (Tuple2<ConnectorTypeInfo, AnyRoundInputConnector> entry : inputConnectors) {
|
||||||
|
result.add(entry.item2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<OutputConnector> getOutputConnectors() {
|
public List<OutputConnector> getOutputConnectors() {
|
||||||
return null;
|
List<OutputConnector> result = new ArrayList<>(outputConnectors.size());
|
||||||
|
for (Tuple2<ConnectorTypeInfo, RoundOutputConnector> entry : outputConnectors) {
|
||||||
|
result.add(entry.item2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JSONObject serialize() throws JSONException {
|
public JSONObject serialize() throws JSONException {
|
||||||
return null;
|
JSONObject serialized = new JSONObject();
|
||||||
|
|
||||||
|
serialized.put("id", _id);
|
||||||
|
serialized.put("left", _left);
|
||||||
|
serialized.put("top", _top);
|
||||||
|
|
||||||
|
JSONObject blockData = _block.serialize();
|
||||||
|
serialized.put("block", blockData);
|
||||||
|
|
||||||
|
// serialized.put("on_string_output_connector",
|
||||||
|
// Serializations.serialize(serializeConnectionEndpoints()));
|
||||||
|
|
||||||
|
return serialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
JSONObject el = data.getJSONObject("block");
|
||||||
|
ProgramakerCustomBlock block = ProgramakerCustomBlock.deserialize(el);
|
||||||
|
ProgramakerCustomBlockPart part = new ProgramakerCustomBlockPart(id, grid, left, top, block);
|
||||||
|
|
||||||
|
List<PartConnection> connections = new LinkedList<>();
|
||||||
|
|
||||||
|
// JSONArray connectorOuts = data.getJSONArray("on_string_output_connector");
|
||||||
|
// for (int i = 0; i < connectorOuts.length(); i++) {
|
||||||
|
// connections.add(PartConnection.deserialize(
|
||||||
|
// toggle._stringOutputConnector,
|
||||||
|
// connectorOuts.getJSONObject(i)));
|
||||||
|
// }
|
||||||
|
|
||||||
|
return new Tuple2<>(part, connections);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void send(InputConnector inputConnector, WireDataType signal) {
|
public void send(InputConnector inputConnector, WireDataType signal) {
|
||||||
|
Log.i(LogTag, "Received signal from Input="+inputConnector);
|
||||||
|
ConnectorTypeInfo info = getConnectorInfo(inputConnector);
|
||||||
|
if (info == null) {
|
||||||
|
Log.e(LogTag, "Unknown connector" + inputConnector);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (info.get_type() == ConnectorTypeInfo.Type.PULSE) {
|
||||||
|
wrappedRunOperation();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int index = getConnectorIndex(inputConnector);
|
||||||
|
if (index < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.lastValues[index] = signal.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void wrappedRunOperation() {
|
||||||
|
Log.i(LogTag, "Running block function=" + this._block.getFunction_name());
|
||||||
|
String token = this.prepareStart();
|
||||||
|
|
||||||
|
if (token != null) {
|
||||||
|
try {
|
||||||
|
new DoAsync().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
|
||||||
|
new Tuple2<>(() -> {
|
||||||
|
ProgramakerCustomBlockPart.this.runBlockOperation();
|
||||||
|
|
||||||
|
ProgramakerCustomBlockPart.this.freeBlock(token);
|
||||||
|
}, param -> {
|
||||||
|
Log.e(LogTag, "Error executing function=" + this._block.getFunction_name()
|
||||||
|
+ "; Error=" + param);
|
||||||
|
ProgramakerCustomBlockPart.this.freeBlock(token);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
Log.e(LogTag, "Error executing function=" + this._block.getFunction_name()
|
||||||
|
+ "; Error=" + ex);
|
||||||
|
this.freeBlock(token);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// An execution is in progress, so nothing is done
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runBlockOperation() {
|
||||||
|
ProgramakerApi api = this._partGrid.getApi();
|
||||||
|
List<String> arguments = new LinkedList<>();
|
||||||
|
|
||||||
|
int index = -1;
|
||||||
|
for (Tuple2<ConnectorTypeInfo, AnyRoundInputConnector> entry : inputConnectors) {
|
||||||
|
index++;
|
||||||
|
if (entry.item1.get_type() == ConnectorTypeInfo.Type.PULSE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
arguments.add(lastValues[index].toString()); // TODO: Do proper type formatting
|
||||||
|
}
|
||||||
|
|
||||||
|
ProgramakerFunctionCallResult result = api.callBlock(this._block, arguments);
|
||||||
|
Log.d(LogTag, "Execution result="+result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void freeBlock(String token) {
|
||||||
|
tryUpdateBlock(token, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String prepareStart() {
|
||||||
|
String token = UUID.randomUUID().toString();
|
||||||
|
if (tryUpdateBlock(null, token)) {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized boolean tryUpdateBlock(String oldVal, String newVal) {
|
||||||
|
if (this.token == oldVal) {
|
||||||
|
this.token = newVal;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String get_id() {
|
public String get_id() {
|
||||||
return _id;
|
return _id;
|
||||||
@ -91,11 +382,54 @@ public class ProgramakerCustomBlockPart implements Part {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputConnector getConnectorWithId(String inputConnectorId) {
|
public InputConnector getConnectorWithId(String inputConnectorId) {
|
||||||
|
if (inputConnectorId.startsWith("index=")) {
|
||||||
|
String[] chunks = inputConnectorId.split("=");
|
||||||
|
if (chunks.length > 1) {
|
||||||
|
Integer index = null;
|
||||||
|
try {
|
||||||
|
index = Integer.parseInt(chunks[1]);
|
||||||
|
}
|
||||||
|
catch (NumberFormatException ex) {
|
||||||
|
Log.e(LogTag, "Error parsing connector id="+inputConnectorId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index != null && index < inputConnectors.size()) {
|
||||||
|
return inputConnectors.get(index).item2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getConnectorIndex(InputConnector inputConnector) {
|
||||||
|
int index = 0;
|
||||||
|
for (Tuple2<ConnectorTypeInfo, AnyRoundInputConnector> entry : inputConnectors) {
|
||||||
|
if (entry.item2 == inputConnector) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getConnectorId(InputConnector inputConnector) {
|
public String getConnectorId(InputConnector inputConnector) {
|
||||||
|
int index = getConnectorIndex(inputConnector);
|
||||||
|
if (index < 0 ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "index=" + index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnectorTypeInfo getConnectorInfo(InputConnector inputConnector) {
|
||||||
|
for (Tuple2<ConnectorTypeInfo, AnyRoundInputConnector> entry : inputConnectors) {
|
||||||
|
if (entry.item2 == inputConnector) {
|
||||||
|
return entry.item1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,12 +445,82 @@ public class ProgramakerCustomBlockPart implements Part {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(ScrolledCanvas canvas, boolean devMode) {
|
public void draw(ScrolledCanvas canvas, boolean devMode) {
|
||||||
// TODO: Implement
|
|
||||||
|
updateWidthHeight(); // TODO: Remove after the calculations have stabilized
|
||||||
|
|
||||||
|
if (!devMode) {
|
||||||
|
return; // Logic block, don't show on user-mode
|
||||||
|
}
|
||||||
|
|
||||||
|
drawConnectors(canvas);
|
||||||
|
// drawWires(canvas, devMode); // TODO: Implement
|
||||||
|
|
||||||
|
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
paint.setColor(Color.WHITE);
|
||||||
|
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) {
|
||||||
|
if (inputConnectors != null) {
|
||||||
|
for (Tuple2<ConnectorTypeInfo, AnyRoundInputConnector> entry : inputConnectors) {
|
||||||
|
Paint outerInputConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
outerInputConnectorPaint.setColor(entry.item1.getOuterColor());
|
||||||
|
|
||||||
|
canvas.drawCircle(
|
||||||
|
entry.item2.getX(),
|
||||||
|
entry.item2.getY(),
|
||||||
|
entry.item2.getRadius(),
|
||||||
|
outerInputConnectorPaint);
|
||||||
|
|
||||||
|
Paint innerInputConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
innerInputConnectorPaint.setColor(entry.item1.getInnerColor());
|
||||||
|
|
||||||
|
canvas.drawCircle(
|
||||||
|
entry.item2.getX(),
|
||||||
|
entry.item2.getY(),
|
||||||
|
entry.item2.getRadius() / 2,
|
||||||
|
innerInputConnectorPaint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outputConnectors != null) {
|
||||||
|
for (Tuple2<ConnectorTypeInfo, RoundOutputConnector> entry : outputConnectors) {
|
||||||
|
Paint outerOutputConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
outerOutputConnectorPaint.setColor(entry.item1.getOuterColor());
|
||||||
|
|
||||||
|
canvas.drawCircle(
|
||||||
|
entry.item2.getX(),
|
||||||
|
entry.item2.getY(),
|
||||||
|
entry.item2.getRadius(),
|
||||||
|
outerOutputConnectorPaint);
|
||||||
|
|
||||||
|
Paint innerOutputConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
innerOutputConnectorPaint.setColor(entry.item1.getInnerColor());
|
||||||
|
|
||||||
|
canvas.drawCircle(
|
||||||
|
entry.item2.getX(),
|
||||||
|
entry.item2.getY(),
|
||||||
|
entry.item2.getRadius() / 2,
|
||||||
|
innerOutputConnectorPaint);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void moveEnd(int x, int y) {
|
public void moveEnd(int x, int y) {
|
||||||
// TODO: Implement moving connectors
|
_left = x - width / 2;
|
||||||
|
_top = y - height / 2;
|
||||||
|
|
||||||
|
this.updatePortPositions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -126,8 +530,9 @@ public class ProgramakerCustomBlockPart implements Part {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean containsPoint(int x, int y) {
|
public boolean containsPoint(int x, int y) {
|
||||||
|
Log.d(LogTag, "Contains (" +x+","+y+") in {left=" +get_left()+",right="+get_right()+",top="+get_top()+",bottom=" + get_bottom() + "}");
|
||||||
return ((x >= this.get_left()) && (x <= this.get_right())
|
return ((x >= this.get_left()) && (x <= this.get_right())
|
||||||
&& (y >= this.get_top()) && (y <= this.get_top()));
|
&& (y >= this.get_top()) && (y <= this.get_bottom()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -7,6 +7,7 @@ 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.RoundOutputConnector;
|
import com.codigoparallevar.minicards.parts.connectors.RoundOutputConnector;
|
||||||
|
import com.codigoparallevar.minicards.parts.style.CardTheme;
|
||||||
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.PartConnection;
|
import com.codigoparallevar.minicards.types.PartConnection;
|
||||||
@ -106,12 +107,19 @@ public class RoundButton implements Part {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void drawConnector(ScrolledCanvas canvas) {
|
private void drawConnector(ScrolledCanvas canvas) {
|
||||||
Paint connectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
Paint outerConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
connectorPaint.setColor(Color.RED);
|
outerConnectorPaint.setColor(CardTheme.PULSE_CONNECTOR_COLOR_OUTER);
|
||||||
|
|
||||||
canvas.drawCircle(getOutputConnectorCenterX(), getOutputConnectorCenterY(),
|
canvas.drawCircle(getOutputConnectorCenterX(), getOutputConnectorCenterY(),
|
||||||
getOutputConnectRadius(),
|
getOutputConnectRadius(),
|
||||||
connectorPaint);
|
outerConnectorPaint);
|
||||||
|
|
||||||
|
Paint innerConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
innerConnectorPaint.setColor(CardTheme.PULSE_CONNECTOR_COLOR_INNER);
|
||||||
|
|
||||||
|
canvas.drawCircle(getOutputConnectorCenterX(), getOutputConnectorCenterY(),
|
||||||
|
getOutputConnectRadius() / 2,
|
||||||
|
innerConnectorPaint);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getOutputConnectorCenterX() {
|
private int getOutputConnectorCenterX() {
|
||||||
|
@ -65,6 +65,10 @@ public class AnyRoundInputConnector extends AnyInputConnector {
|
|||||||
return _yposition;
|
return _yposition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float getRadius() {
|
||||||
|
return _radius;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void send(WireDataType signal) {
|
public void send(WireDataType signal) {
|
||||||
_part.send(this, signal);
|
_part.send(this, signal);
|
||||||
|
@ -0,0 +1,105 @@
|
|||||||
|
package com.codigoparallevar.minicards.parts.connectors;
|
||||||
|
|
||||||
|
import com.codigoparallevar.minicards.parts.style.CardTheme;
|
||||||
|
|
||||||
|
public class ConnectorTypeInfo {
|
||||||
|
private final Type _type;
|
||||||
|
|
||||||
|
public static ConnectorTypeInfo FromTypeName(String type) {
|
||||||
|
if (type == null) {
|
||||||
|
return new ConnectorTypeInfo(Type.UNKNOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
type = type.toLowerCase();
|
||||||
|
if (type.equals("string")) {
|
||||||
|
return new ConnectorTypeInfo(Type.STRING);
|
||||||
|
}
|
||||||
|
else if (type.equals("integer")) {
|
||||||
|
return new ConnectorTypeInfo(Type.INTEGER);
|
||||||
|
}
|
||||||
|
else if (type.equals("float")) {
|
||||||
|
return new ConnectorTypeInfo(Type.FLOAT);
|
||||||
|
}
|
||||||
|
else if (type.equals("boolean")) {
|
||||||
|
return new ConnectorTypeInfo(Type.BOOLEAN);
|
||||||
|
}
|
||||||
|
else if (type.equals("pulse")) {
|
||||||
|
return new ConnectorTypeInfo(Type.PULSE);
|
||||||
|
}
|
||||||
|
else if (type.equals("enum")) {
|
||||||
|
return new ConnectorTypeInfo(Type.ENUM);
|
||||||
|
}
|
||||||
|
else if (type.equals("any")) {
|
||||||
|
return new ConnectorTypeInfo(Type.ANY);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return new ConnectorTypeInfo(Type.UNKNOWN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOuterColor() {
|
||||||
|
switch (_type) {
|
||||||
|
case ANY:
|
||||||
|
return CardTheme.ANY_CONNECTOR_COLOR_OUTER;
|
||||||
|
case ENUM:
|
||||||
|
return CardTheme.ENUM_CONNECTOR_COLOR_OUTER;
|
||||||
|
case FLOAT:
|
||||||
|
return CardTheme.FLOAT_CONNECTOR_COLOR_OUTER;
|
||||||
|
case PULSE:
|
||||||
|
return CardTheme.PULSE_CONNECTOR_COLOR_OUTER;
|
||||||
|
case STRING:
|
||||||
|
return CardTheme.STRING_CONNECTOR_COLOR_OUTER;
|
||||||
|
case BOOLEAN:
|
||||||
|
return CardTheme.BOOLEAN_CONNECTOR_COLOR_OUTER;
|
||||||
|
case INTEGER:
|
||||||
|
return CardTheme.INTEGER_CONNECTOR_COLOR_OUTER;
|
||||||
|
case UNKNOWN:
|
||||||
|
return CardTheme.UNKNOWN_CONNECTOR_COLOR_OUTER;
|
||||||
|
default:
|
||||||
|
return CardTheme.UNKNOWN_CONNECTOR_COLOR_OUTER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getInnerColor() {
|
||||||
|
switch (_type) {
|
||||||
|
case ANY:
|
||||||
|
return CardTheme.ANY_CONNECTOR_COLOR_INNER;
|
||||||
|
case ENUM:
|
||||||
|
return CardTheme.ENUM_CONNECTOR_COLOR_INNER;
|
||||||
|
case FLOAT:
|
||||||
|
return CardTheme.FLOAT_CONNECTOR_COLOR_INNER;
|
||||||
|
case PULSE:
|
||||||
|
return CardTheme.PULSE_CONNECTOR_COLOR_INNER;
|
||||||
|
case STRING:
|
||||||
|
return CardTheme.STRING_CONNECTOR_COLOR_INNER;
|
||||||
|
case BOOLEAN:
|
||||||
|
return CardTheme.BOOLEAN_CONNECTOR_COLOR_INNER;
|
||||||
|
case INTEGER:
|
||||||
|
return CardTheme.INTEGER_CONNECTOR_COLOR_INNER;
|
||||||
|
case UNKNOWN:
|
||||||
|
return CardTheme.UNKNOWN_CONNECTOR_COLOR_INNER;
|
||||||
|
default:
|
||||||
|
return CardTheme.UNKNOWN_CONNECTOR_COLOR_INNER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Type {
|
||||||
|
PULSE,
|
||||||
|
BOOLEAN,
|
||||||
|
STRING,
|
||||||
|
ANY,
|
||||||
|
ENUM,
|
||||||
|
UNKNOWN,
|
||||||
|
FLOAT,
|
||||||
|
INTEGER,
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnectorTypeInfo(ConnectorTypeInfo.Type type) {
|
||||||
|
this._type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type get_type() {
|
||||||
|
return _type;
|
||||||
|
}
|
||||||
|
}
|
@ -65,12 +65,15 @@ public class RoundInputConnector implements SignalInputConnector {
|
|||||||
return _yposition;
|
return _yposition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float getRadius() {
|
||||||
|
return _radius;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void send(Signal signal) {
|
public void send(Signal signal) {
|
||||||
_part.send(this, signal);
|
_part.send(this, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getAttachment(Wire<Signal, SignalInputConnector> wire) {
|
public void getAttachment(Wire<Signal, SignalInputConnector> wire) {
|
||||||
_attachments.add(wire);
|
_attachments.add(wire);
|
||||||
|
@ -155,4 +155,16 @@ public class RoundOutputConnector implements Drawable, SignalOutputConnector {
|
|||||||
wire.send(signal);
|
wire.send(signal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float getX() {
|
||||||
|
return _centerX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getY() {
|
||||||
|
return _centerY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getRadius() {
|
||||||
|
return _radius;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ 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.RoundOutputConnector;
|
import com.codigoparallevar.minicards.parts.connectors.RoundOutputConnector;
|
||||||
|
import com.codigoparallevar.minicards.parts.style.CardTheme;
|
||||||
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.PartConnection;
|
import com.codigoparallevar.minicards.types.PartConnection;
|
||||||
@ -144,13 +145,21 @@ public class Ticker implements Part {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void drawConnector(ScrolledCanvas canvas) {
|
private void drawConnector(ScrolledCanvas canvas) {
|
||||||
Paint connectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
Paint outerConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
connectorPaint.setColor(Color.RED);
|
outerConnectorPaint.setColor(CardTheme.PULSE_CONNECTOR_COLOR_OUTER);
|
||||||
|
|
||||||
canvas.drawCircle(getOutputConnectorCenterX(),
|
canvas.drawCircle(getOutputConnectorCenterX(),
|
||||||
getOutputConnectorCenterY(),
|
getOutputConnectorCenterY(),
|
||||||
getOutputConnectRadius(),
|
getOutputConnectRadius(),
|
||||||
connectorPaint);
|
outerConnectorPaint);
|
||||||
|
|
||||||
|
Paint innerConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
innerConnectorPaint.setColor(CardTheme.PULSE_CONNECTOR_COLOR_INNER);
|
||||||
|
|
||||||
|
canvas.drawCircle(getOutputConnectorCenterX(),
|
||||||
|
getOutputConnectorCenterY(),
|
||||||
|
getOutputConnectRadius() / 2,
|
||||||
|
innerConnectorPaint);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void drawWires(ScrolledCanvas canvas, boolean devMode) {
|
private void drawWires(ScrolledCanvas canvas, boolean devMode) {
|
||||||
|
@ -9,6 +9,7 @@ import com.codigoparallevar.minicards.PartInstantiator;
|
|||||||
import com.codigoparallevar.minicards.ScrolledCanvas;
|
import com.codigoparallevar.minicards.ScrolledCanvas;
|
||||||
import com.codigoparallevar.minicards.parts.connectors.BooleanRoundOutputConnector;
|
import com.codigoparallevar.minicards.parts.connectors.BooleanRoundOutputConnector;
|
||||||
import com.codigoparallevar.minicards.parts.connectors.RoundInputConnector;
|
import com.codigoparallevar.minicards.parts.connectors.RoundInputConnector;
|
||||||
|
import com.codigoparallevar.minicards.parts.style.CardTheme;
|
||||||
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.PartConnection;
|
import com.codigoparallevar.minicards.types.PartConnection;
|
||||||
@ -128,22 +129,41 @@ public class Toggle implements Part {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void drawConnector(ScrolledCanvas canvas) {
|
private void drawConnector(ScrolledCanvas canvas) {
|
||||||
Paint inputConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
// Input
|
||||||
inputConnectorPaint.setColor(Color.YELLOW);
|
Paint outerInputConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
outerInputConnectorPaint.setColor(CardTheme.PULSE_CONNECTOR_COLOR_OUTER);
|
||||||
|
|
||||||
canvas.drawCircle(
|
canvas.drawCircle(
|
||||||
getInputConnectorCenterX(),
|
getInputConnectorCenterX(),
|
||||||
getInputConnectorCenterY(),
|
getInputConnectorCenterY(),
|
||||||
getInputConnectRadius(),
|
getInputConnectRadius(),
|
||||||
inputConnectorPaint);
|
outerInputConnectorPaint);
|
||||||
|
|
||||||
Paint outputConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
Paint innerInputConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
outputConnectorPaint.setColor(Color.RED);
|
innerInputConnectorPaint.setColor(CardTheme.PULSE_CONNECTOR_COLOR_INNER);
|
||||||
|
|
||||||
|
canvas.drawCircle(
|
||||||
|
getInputConnectorCenterX(),
|
||||||
|
getInputConnectorCenterY(),
|
||||||
|
getInputConnectRadius() / 2,
|
||||||
|
innerInputConnectorPaint);
|
||||||
|
|
||||||
|
// Output
|
||||||
|
Paint outerOutputConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
outerOutputConnectorPaint.setColor(CardTheme.BOOLEAN_CONNECTOR_COLOR_OUTER);
|
||||||
|
|
||||||
canvas.drawCircle(getOutputConnectorCenterX(),
|
canvas.drawCircle(getOutputConnectorCenterX(),
|
||||||
getOutputConnectorCenterY(),
|
getOutputConnectorCenterY(),
|
||||||
getOutputConnectRadius(),
|
getOutputConnectRadius(),
|
||||||
outputConnectorPaint);
|
outerOutputConnectorPaint);
|
||||||
|
|
||||||
|
Paint innerOutputConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
innerOutputConnectorPaint.setColor(CardTheme.BOOLEAN_CONNECTOR_COLOR_INNER);
|
||||||
|
|
||||||
|
canvas.drawCircle(getOutputConnectorCenterX(),
|
||||||
|
getOutputConnectorCenterY(),
|
||||||
|
getOutputConnectRadius() / 2,
|
||||||
|
innerOutputConnectorPaint);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void drawWires(ScrolledCanvas canvas, boolean devMode) {
|
private void drawWires(ScrolledCanvas canvas, boolean devMode) {
|
||||||
|
@ -8,6 +8,7 @@ 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.BooleanRoundInputConnector;
|
import com.codigoparallevar.minicards.parts.connectors.BooleanRoundInputConnector;
|
||||||
|
import com.codigoparallevar.minicards.parts.style.CardTheme;
|
||||||
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;
|
||||||
@ -105,14 +106,23 @@ public class ColorBox implements Part {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void drawConnector(ScrolledCanvas canvas) {
|
private void drawConnector(ScrolledCanvas canvas) {
|
||||||
Paint connectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
Paint outerInputConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
connectorPaint.setColor(Color.YELLOW);
|
outerInputConnectorPaint.setColor(CardTheme.BOOLEAN_CONNECTOR_COLOR_OUTER);
|
||||||
|
|
||||||
canvas.drawCircle(
|
canvas.drawCircle(
|
||||||
getInputConnectorCenterX(),
|
getInputConnectorCenterX(),
|
||||||
getInputConnectorCenterY(),
|
getInputConnectorCenterY(),
|
||||||
getInputConnectRadius(),
|
getInputConnectRadius(),
|
||||||
connectorPaint);
|
outerInputConnectorPaint);
|
||||||
|
|
||||||
|
Paint innerInputConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
innerInputConnectorPaint.setColor(CardTheme.BOOLEAN_CONNECTOR_COLOR_INNER);
|
||||||
|
|
||||||
|
canvas.drawCircle(
|
||||||
|
getInputConnectorCenterX(),
|
||||||
|
getInputConnectorCenterY(),
|
||||||
|
getInputConnectRadius() / 2,
|
||||||
|
innerInputConnectorPaint);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -10,6 +10,7 @@ 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.AnyRoundInputConnector;
|
||||||
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.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.PartConnection;
|
import com.codigoparallevar.minicards.types.PartConnection;
|
||||||
@ -127,22 +128,41 @@ public class ConvertToString implements Part {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void drawConnector(ScrolledCanvas canvas) {
|
private void drawConnector(ScrolledCanvas canvas) {
|
||||||
Paint inputConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
// Input
|
||||||
inputConnectorPaint.setColor(Color.YELLOW);
|
Paint inputOuterConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
inputOuterConnectorPaint.setColor(CardTheme.ANY_CONNECTOR_COLOR_OUTER);
|
||||||
|
|
||||||
canvas.drawCircle(
|
canvas.drawCircle(
|
||||||
getInputConnectorCenterX(),
|
getInputConnectorCenterX(),
|
||||||
getInputConnectorCenterY(),
|
getInputConnectorCenterY(),
|
||||||
getInputConnectRadius(),
|
getInputConnectRadius(),
|
||||||
inputConnectorPaint);
|
inputOuterConnectorPaint);
|
||||||
|
|
||||||
Paint outputConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
Paint inputInnerConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
outputConnectorPaint.setColor(Color.RED);
|
inputInnerConnectorPaint.setColor(CardTheme.ANY_CONNECTOR_COLOR_INNER);
|
||||||
|
|
||||||
|
canvas.drawCircle(
|
||||||
|
getInputConnectorCenterX(),
|
||||||
|
getInputConnectorCenterY(),
|
||||||
|
getInputConnectRadius() / 2,
|
||||||
|
inputInnerConnectorPaint);
|
||||||
|
|
||||||
|
// Output
|
||||||
|
Paint outputOuterConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
outputOuterConnectorPaint.setColor(CardTheme.STRING_CONNECTOR_COLOR_OUTER);
|
||||||
|
|
||||||
canvas.drawCircle(getOutputConnectorCenterX(),
|
canvas.drawCircle(getOutputConnectorCenterX(),
|
||||||
getOutputConnectorCenterY(),
|
getOutputConnectorCenterY(),
|
||||||
getOutputConnectRadius(),
|
getOutputConnectRadius(),
|
||||||
outputConnectorPaint);
|
outputOuterConnectorPaint);
|
||||||
|
|
||||||
|
Paint outputInnerConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
outputInnerConnectorPaint.setColor(CardTheme.STRING_CONNECTOR_COLOR_INNER);
|
||||||
|
|
||||||
|
canvas.drawCircle(getOutputConnectorCenterX(),
|
||||||
|
getOutputConnectorCenterY(),
|
||||||
|
getOutputConnectRadius() / 2,
|
||||||
|
outputInnerConnectorPaint);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void drawWires(ScrolledCanvas canvas, boolean devMode) {
|
private void drawWires(ScrolledCanvas canvas, boolean devMode) {
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.codigoparallevar.minicards.parts.style;
|
||||||
|
|
||||||
|
import android.graphics.Color;
|
||||||
|
|
||||||
|
public class CardTheme {
|
||||||
|
public static final int DEFAULT_COLOR_INNER = Color.parseColor("#000000");
|
||||||
|
|
||||||
|
public static final int PULSE_CONNECTOR_COLOR_OUTER = Color.parseColor("#f0c000");
|
||||||
|
public static final int PULSE_CONNECTOR_COLOR_INNER = DEFAULT_COLOR_INNER;
|
||||||
|
|
||||||
|
public static final int BOOLEAN_CONNECTOR_COLOR_OUTER = Color.parseColor("#dd4444");
|
||||||
|
public static final int BOOLEAN_CONNECTOR_COLOR_INNER = DEFAULT_COLOR_INNER;
|
||||||
|
|
||||||
|
public static final int STRING_CONNECTOR_COLOR_OUTER = Color.parseColor("#44dd44");
|
||||||
|
public static final int STRING_CONNECTOR_COLOR_INNER = DEFAULT_COLOR_INNER;
|
||||||
|
|
||||||
|
public static final int ANY_CONNECTOR_COLOR_OUTER = Color.parseColor("#dd44dd");
|
||||||
|
public static final int ANY_CONNECTOR_COLOR_INNER = DEFAULT_COLOR_INNER;
|
||||||
|
|
||||||
|
public static final int ENUM_CONNECTOR_COLOR_OUTER = Color.parseColor("#888888");
|
||||||
|
public static final int ENUM_CONNECTOR_COLOR_INNER = DEFAULT_COLOR_INNER;
|
||||||
|
|
||||||
|
public static final int FLOAT_CONNECTOR_COLOR_OUTER = Color.parseColor("#44dddd");
|
||||||
|
public static final int FLOAT_CONNECTOR_COLOR_INNER = DEFAULT_COLOR_INNER;
|
||||||
|
|
||||||
|
public static final int INTEGER_CONNECTOR_COLOR_OUTER = Color.parseColor("#4444ff");
|
||||||
|
public static final int INTEGER_CONNECTOR_COLOR_INNER = DEFAULT_COLOR_INNER;
|
||||||
|
|
||||||
|
public static final int UNKNOWN_CONNECTOR_COLOR_OUTER = Color.parseColor("#7f7f7f");
|
||||||
|
public static final int UNKNOWN_CONNECTOR_COLOR_INNER = DEFAULT_COLOR_INNER;
|
||||||
|
}
|
@ -4,9 +4,11 @@ import com.codigoparallevar.minicards.types.connectors.input.BooleanInputConnect
|
|||||||
import com.codigoparallevar.minicards.types.connectors.input.SignalInputConnector;
|
import com.codigoparallevar.minicards.types.connectors.input.SignalInputConnector;
|
||||||
import com.codigoparallevar.minicards.types.connectors.input.StringInputConnector;
|
import com.codigoparallevar.minicards.types.connectors.input.StringInputConnector;
|
||||||
import com.codigoparallevar.minicards.types.functional.Tuple2;
|
import com.codigoparallevar.minicards.types.functional.Tuple2;
|
||||||
|
import com.programaker.api.ProgramakerApi;
|
||||||
|
|
||||||
public interface PartGrid {
|
public interface PartGrid {
|
||||||
Selectable getPartOn(int x, int y);
|
Selectable getPartOn(int x, int y);
|
||||||
|
ProgramakerApi getApi();
|
||||||
|
|
||||||
SignalInputConnector getSignalInputConnectorOn(int x, int y);
|
SignalInputConnector getSignalInputConnectorOn(int x, int y);
|
||||||
BooleanInputConnector getBooleanInputConnectorOn(int x, int y);
|
BooleanInputConnector getBooleanInputConnectorOn(int x, int y);
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.codigoparallevar.minicards.types.functional;
|
||||||
|
|
||||||
|
public interface Action {
|
||||||
|
void run() throws InterruptedException;
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
package com.codigoparallevar.minicards.types.functional;
|
package com.codigoparallevar.minicards.types.functional;
|
||||||
|
|
||||||
public abstract class Consumer<T> {
|
public interface Consumer<T> {
|
||||||
public abstract void apply(T param);
|
void apply(T param);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
package com.codigoparallevar.minicards.types.functional;
|
package com.codigoparallevar.minicards.types.functional;
|
||||||
|
|
||||||
public abstract class Producer<T> {
|
public interface Producer<T> {
|
||||||
public abstract T get();
|
T get();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.codigoparallevar.minicards.ui_helpers;
|
||||||
|
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
|
||||||
|
import com.codigoparallevar.minicards.types.functional.Action;
|
||||||
|
import com.codigoparallevar.minicards.types.functional.Consumer;
|
||||||
|
import com.codigoparallevar.minicards.types.functional.Tuple2;
|
||||||
|
|
||||||
|
public class DoAsync extends AsyncTask<Tuple2<Action, Consumer<Throwable>>,
|
||||||
|
Void, Void> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Void doInBackground(Tuple2<Action, Consumer<Throwable>>... data) {
|
||||||
|
try {
|
||||||
|
data[0].item1.run();
|
||||||
|
}
|
||||||
|
catch (Throwable ex) {
|
||||||
|
data[0].item2.apply(ex);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -6,10 +6,12 @@ import com.google.gson.Gson
|
|||||||
import com.google.gson.GsonBuilder
|
import com.google.gson.GsonBuilder
|
||||||
import com.programaker.api.data.ProgramakerBridgeInfo
|
import com.programaker.api.data.ProgramakerBridgeInfo
|
||||||
import com.programaker.api.data.ProgramakerCustomBlock
|
import com.programaker.api.data.ProgramakerCustomBlock
|
||||||
|
import com.programaker.api.data.ProgramakerFunctionCallResult
|
||||||
import com.programaker.api.data.api_results.*
|
import com.programaker.api.data.api_results.*
|
||||||
import com.programaker.api.exceptions.ProgramakerLoginRequiredException
|
import com.programaker.api.exceptions.ProgramakerLoginRequiredException
|
||||||
import com.programaker.api.exceptions.ProgramakerProtocolException
|
import com.programaker.api.exceptions.ProgramakerProtocolException
|
||||||
import com.programaker.api.exceptions.TokenNotFoundException
|
import com.programaker.api.exceptions.TokenNotFoundException
|
||||||
|
import org.json.JSONArray
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import java.io.DataOutputStream
|
import java.io.DataOutputStream
|
||||||
import java.io.FileNotFoundException
|
import java.io.FileNotFoundException
|
||||||
@ -104,6 +106,10 @@ class ProgramakerApi(private val ApiRoot: String="https://programaker.com/api")
|
|||||||
ex.logError(LogTag)
|
ex.logError(LogTag)
|
||||||
throw ProgramakerProtocolException()
|
throw ProgramakerProtocolException()
|
||||||
}
|
}
|
||||||
|
catch (ex: Exception) {
|
||||||
|
Log.e(LogTag, "Unexpected exception: " + ex)
|
||||||
|
throw ProgramakerProtocolException()
|
||||||
|
}
|
||||||
return result.result
|
return result.result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,6 +137,27 @@ class ProgramakerApi(private val ApiRoot: String="https://programaker.com/api")
|
|||||||
}
|
}
|
||||||
return result.result
|
return result.result
|
||||||
}
|
}
|
||||||
|
fun callBlock(block: ProgramakerCustomBlock, arguments: List<String>): ProgramakerFunctionCallResult {
|
||||||
|
val conn = URL(getBlockUrl(block)).openConnection() as HttpURLConnection
|
||||||
|
conn.setRequestProperty("Content-Type", "application/json")
|
||||||
|
addAuthHeader(conn)
|
||||||
|
|
||||||
|
conn.requestMethod = "POST";
|
||||||
|
conn.doOutput = true;
|
||||||
|
|
||||||
|
val postData = JSONObject(hashMapOf(
|
||||||
|
"arguments" to JSONArray(arguments)
|
||||||
|
) as Map<*, *>)
|
||||||
|
|
||||||
|
val wr = DataOutputStream(conn.outputStream)
|
||||||
|
wr.writeBytes(postData.toString());
|
||||||
|
wr.flush();
|
||||||
|
wr.close();
|
||||||
|
|
||||||
|
val result: ProgramakerFunctionCallResult
|
||||||
|
result = parseJson(conn.inputStream, ProgramakerFunctionCallResult::class.java)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
// Initialization
|
// Initialization
|
||||||
init {
|
init {
|
||||||
@ -160,6 +187,11 @@ class ProgramakerApi(private val ApiRoot: String="https://programaker.com/api")
|
|||||||
return "$ApiRoot/v0/users/$userName/bridges/"
|
return "$ApiRoot/v0/users/$userName/bridges/"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getBlockUrl(block: ProgramakerCustomBlock): String {
|
||||||
|
this.withUserId()
|
||||||
|
return "$ApiRoot/v0/users/id/$userId/bridges/id/${block.bridge_id}/functions/${block.function_name}"
|
||||||
|
}
|
||||||
|
|
||||||
private fun withUserName() {
|
private fun withUserName() {
|
||||||
if (userName == null) {
|
if (userName == null) {
|
||||||
if (token == null) {
|
if (token == null) {
|
||||||
@ -173,6 +205,19 @@ class ProgramakerApi(private val ApiRoot: String="https://programaker.com/api")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun withUserId() {
|
||||||
|
if (userId == null) {
|
||||||
|
if (token == null) {
|
||||||
|
throw ProgramakerLoginRequiredException()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.check();
|
||||||
|
if (userId == null) {
|
||||||
|
throw ProgramakerProtocolException()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun addAuthHeader(conn: URLConnection) {
|
private fun addAuthHeader(conn: URLConnection) {
|
||||||
if (token != null) {
|
if (token != null) {
|
||||||
conn.setRequestProperty("Authorization", token)
|
conn.setRequestProperty("Authorization", token)
|
||||||
|
@ -1,14 +1,62 @@
|
|||||||
package com.programaker.api.data
|
package com.programaker.api.data
|
||||||
|
|
||||||
|
import org.json.JSONArray
|
||||||
|
import org.json.JSONObject
|
||||||
|
|
||||||
class ProgramakerCustomBlock(
|
class ProgramakerCustomBlock(
|
||||||
val id: String,
|
|
||||||
val service_port_id: String,
|
|
||||||
val block_id: String,
|
val block_id: String,
|
||||||
val block_type: String,
|
|
||||||
val block_result_type: String,
|
|
||||||
val function_name: String,
|
val function_name: String,
|
||||||
val message: String
|
val message: String,
|
||||||
// val arguments: BlockArgument[],
|
val arguments: List<ProgramakerCustomBlockArgument>?,
|
||||||
// val save_to: undefined | string,
|
val block_type: String?,
|
||||||
|
val block_result_type: String?,
|
||||||
|
var bridge_id: String?,
|
||||||
|
val save_to: ProgramakerCustomBlockSaveTo?
|
||||||
) {
|
) {
|
||||||
|
fun serialize(): JSONObject {
|
||||||
|
|
||||||
|
val serializedArguments = JSONArray()
|
||||||
|
if (arguments != null) {
|
||||||
|
for (value in arguments) {
|
||||||
|
serializedArguments.put(value.serialize())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var saveToSerialized: JSONObject? = null
|
||||||
|
if (save_to != null) {
|
||||||
|
saveToSerialized = save_to.serialize()
|
||||||
|
}
|
||||||
|
|
||||||
|
val serialized = hashMapOf(
|
||||||
|
"block_id" to block_id,
|
||||||
|
"function_name" to function_name,
|
||||||
|
"message" to message,
|
||||||
|
"arguments" to serializedArguments,
|
||||||
|
"block_type" to block_type,
|
||||||
|
"block_result_type" to block_result_type,
|
||||||
|
"bridge_id" to bridge_id,
|
||||||
|
"save_to" to saveToSerialized
|
||||||
|
);
|
||||||
|
|
||||||
|
return JSONObject(serialized as Map<*, *>)
|
||||||
|
}
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun deserialize(obj: JSONObject): ProgramakerCustomBlock {
|
||||||
|
var block = ProgramakerCustomBlock(
|
||||||
|
obj.getString("block_id"),
|
||||||
|
obj.getString("function_name"),
|
||||||
|
obj.getString("message"),
|
||||||
|
ProgramakerCustomBlockArgument.deserialize(obj.optJSONArray("arguments")),
|
||||||
|
obj.getString("block_type"),
|
||||||
|
obj.getString("block_result_type"),
|
||||||
|
obj.optString("bridge_id"),
|
||||||
|
ProgramakerCustomBlockSaveTo.deserialize(obj.optJSONObject("save_to"))
|
||||||
|
)
|
||||||
|
|
||||||
|
return block
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
package com.programaker.api.data
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import org.json.JSONArray
|
||||||
|
import org.json.JSONObject
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class ProgramakerCustomBlockArgument(
|
||||||
|
val type: String?,
|
||||||
|
val default_value: String?,
|
||||||
|
// val class: String,
|
||||||
|
val callback: String?
|
||||||
|
) {
|
||||||
|
fun serialize(): JSONObject {
|
||||||
|
val serialized = hashMapOf<String, JSONObject>()
|
||||||
|
|
||||||
|
return JSONObject(serialized as Map<*, *>)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun deserialize(arguments: JSONArray?): List<ProgramakerCustomBlockArgument> {
|
||||||
|
if (arguments == null) {
|
||||||
|
return listOf();
|
||||||
|
}
|
||||||
|
val results: MutableList<ProgramakerCustomBlockArgument> = LinkedList()
|
||||||
|
|
||||||
|
var i = 0;
|
||||||
|
while (i < arguments.length()) {
|
||||||
|
val obj = arguments.getJSONObject(i)
|
||||||
|
if (obj == null) {
|
||||||
|
Log.e("PMCustomBlockArgument", "Looped into a null value!?")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
results.add(deserialize(obj))
|
||||||
|
}
|
||||||
|
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun deserialize(arguments: JSONObject): ProgramakerCustomBlockArgument {
|
||||||
|
var type: String? = null
|
||||||
|
var default_value: String? = null
|
||||||
|
var callback: String? = null
|
||||||
|
|
||||||
|
if (arguments.has("type")) {
|
||||||
|
type = arguments.getString("type")
|
||||||
|
}
|
||||||
|
if (arguments.has("default_value")) {
|
||||||
|
default_value = arguments.getString("default_value")
|
||||||
|
}
|
||||||
|
if (arguments.has("callback")) {
|
||||||
|
callback = arguments.getString("callback")
|
||||||
|
}
|
||||||
|
|
||||||
|
return ProgramakerCustomBlockArgument(type, default_value, callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.programaker.api.data
|
||||||
|
|
||||||
|
import org.json.JSONObject
|
||||||
|
|
||||||
|
class ProgramakerCustomBlockSaveTo (
|
||||||
|
val type: String,
|
||||||
|
val index: Int
|
||||||
|
) {
|
||||||
|
fun serialize(): JSONObject {
|
||||||
|
return JSONObject(hashMapOf(
|
||||||
|
"type" to type,
|
||||||
|
"index" to index
|
||||||
|
) as Map<*, *>)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun deserialize(save_to: JSONObject?): ProgramakerCustomBlockSaveTo? {
|
||||||
|
if (save_to == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ProgramakerCustomBlockSaveTo(save_to.getString("type"),
|
||||||
|
save_to.getInt("index"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.programaker.api.data
|
||||||
|
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class ProgramakerFunctionCallResult (
|
||||||
|
var success: Boolean,
|
||||||
|
var result: Object
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
@ -22,10 +22,12 @@ internal class ProgramakerGetCustomBlocksResultTypeAdapter : JsonSerializer<Prog
|
|||||||
|
|
||||||
for (value in value1.asJsonArray) {
|
for (value in value1.asJsonArray) {
|
||||||
val block = gson.fromJson(value, ProgramakerCustomBlock::class.java)
|
val block = gson.fromJson(value, ProgramakerCustomBlock::class.java)
|
||||||
|
block.bridge_id = bridgeId
|
||||||
blocks.add(block)
|
blocks.add(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
val bridge = ProgramakerBridgeCustomBlockResult(bridgeId, blocks)
|
val bridge = ProgramakerBridgeCustomBlockResult(bridgeId, blocks)
|
||||||
|
|
||||||
bridges.add(bridge)
|
bridges.add(bridge)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
5
app/src/main/res/drawable/ic_exit_to_app.xml
Normal file
5
app/src/main/res/drawable/ic_exit_to_app.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<vector android:alpha="0.99" android:height="24dp"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="#FF7F7F7F" android:pathData="M10.09,15.59L11.5,17l5,-5 -5,-5 -1.41,1.41L12.67,11H3v2h9.67l-2.58,2.59zM19,3H5c-1.11,0 -2,0.9 -2,2v4h2V5h14v14H5v-4H3v4c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2V5c0,-1.1 -0.9,-2 -2,-2z"/>
|
||||||
|
</vector>
|
@ -63,7 +63,8 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
fab:fab_colorNormal="@color/white"
|
fab:fab_colorNormal="@color/white"
|
||||||
fab:fab_title="Show deck"
|
app:fab_icon="@drawable/ic_exit_to_app"
|
||||||
|
app:fab_title="@string/go_back"
|
||||||
fab:fab_colorPressed="@color/white_pressed"/>
|
fab:fab_colorPressed="@color/white_pressed"/>
|
||||||
|
|
||||||
<com.getbase.floatingactionbutton.FloatingActionButton
|
<com.getbase.floatingactionbutton.FloatingActionButton
|
||||||
@ -115,8 +116,9 @@
|
|||||||
android:id="@+id/show_deck_from_dev_mode_button"
|
android:id="@+id/show_deck_from_dev_mode_button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
app:fab_icon="@drawable/ic_exit_to_app"
|
||||||
|
app:fab_title="@string/go_back"
|
||||||
fab:fab_colorNormal="@color/white"
|
fab:fab_colorNormal="@color/white"
|
||||||
fab:fab_title="Show deck"
|
|
||||||
fab:fab_colorPressed="@color/white_pressed" />
|
fab:fab_colorPressed="@color/white_pressed" />
|
||||||
|
|
||||||
<com.getbase.floatingactionbutton.FloatingActionButton
|
<com.getbase.floatingactionbutton.FloatingActionButton
|
||||||
|
@ -16,4 +16,6 @@
|
|||||||
<string name="loading">Loading...</string>
|
<string name="loading">Loading...</string>
|
||||||
<string name="invalid_user_pass">Invalid username/password</string>
|
<string name="invalid_user_pass">Invalid username/password</string>
|
||||||
<string name="placeholder_text">Placeholder text</string>
|
<string name="placeholder_text">Placeholder text</string>
|
||||||
|
<string name="back_to_deck">Back to card Deck</string>
|
||||||
|
<string name="go_back">Go back</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -8,7 +8,7 @@ buildscript {
|
|||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.6.1'
|
classpath 'com.android.tools.build:gradle:3.6.3'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user