WIP: Add simple image capture/viewing blocks.
This commit is contained in:
parent
f8786abc14
commit
f82edf041c
@ -2,18 +2,25 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.codigoparallevar.minicards">
|
package="com.codigoparallevar.minicards">
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<!-- Network state on programaker bridge -->
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" android:required="false" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" android:required="false" />
|
||||||
|
<!-- For Wifi SSID -->
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:required="false" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:required="false" />
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" android:required="false" />
|
||||||
|
<!-- For vibration block on bridge -->
|
||||||
|
<uses-permission android:name="android.permission.VIBRATE" android:required="false" />
|
||||||
|
<!-- For Camera block -->
|
||||||
|
<uses-permission android:name="android.permission.CAMERA" android:required="false" />
|
||||||
|
|
||||||
<!-- OpenGL ES 2.0 -->
|
<!-- OpenGL ES 2.0 -->
|
||||||
<uses-feature
|
<uses-feature
|
||||||
android:glEsVersion="0x00020000"
|
android:glEsVersion="0x00020000"
|
||||||
android:required="true" />
|
android:required="true" />
|
||||||
|
<uses-feature android:name="android.hardware.camera" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
<uses-feature android:name="android.hardware.camera.autofocus" />
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- For Programaker bridge -->
|
|
||||||
<uses-permission android:name="android.permission.VIBRATE" />
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
@ -23,6 +23,7 @@ import com.codigoparallevar.minicards.types.connectors.Wiring.SignalWire;
|
|||||||
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.connectors.input.BooleanInputConnector;
|
import com.codigoparallevar.minicards.types.connectors.input.BooleanInputConnector;
|
||||||
|
import com.codigoparallevar.minicards.types.connectors.input.ImageInputConnector;
|
||||||
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;
|
||||||
@ -517,6 +518,31 @@ public class CanvasView extends View implements PartGrid {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ImageInputConnector getImageInputConnectorOn(int x, int y) {
|
||||||
|
// If no part was found, do the same for connectors
|
||||||
|
for (int i = parts.size() - 1; i >= 0; i--){
|
||||||
|
final Part part = parts.get(i);
|
||||||
|
|
||||||
|
// Then with input ones
|
||||||
|
for (InputConnector inputConnector : part.getInputConnectors()){
|
||||||
|
ImageInputConnector imageInputConnector;
|
||||||
|
if (inputConnector instanceof ImageInputConnector){
|
||||||
|
imageInputConnector = (ImageInputConnector) inputConnector;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imageInputConnector.containsPoint(x, y)){
|
||||||
|
return imageInputConnector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void addPart(Part part) {
|
public void addPart(Part part) {
|
||||||
parts.add(part);
|
parts.add(part);
|
||||||
@ -581,4 +607,8 @@ public class CanvasView extends View implements PartGrid {
|
|||||||
part.pause();
|
part.pause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void requestPermission(String permission, Runnable ifAccepted) {
|
||||||
|
this.parentActivity.requestPermissions(permission, ifAccepted);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,15 @@ package com.codigoparallevar.minicards;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
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.appcompat.app.ActionBar;
|
import androidx.appcompat.app.ActionBar;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
@ -22,7 +25,9 @@ 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 java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class CardActivity extends AppCompatActivity {
|
public class CardActivity extends AppCompatActivity {
|
||||||
|
|
||||||
@ -32,6 +37,9 @@ public class CardActivity extends AppCompatActivity {
|
|||||||
public static final String DEVELOPER_VISUALIZATION_MODE = "DEVELOPER_VISUALIZATION_MODE";
|
public static final String DEVELOPER_VISUALIZATION_MODE = "DEVELOPER_VISUALIZATION_MODE";
|
||||||
public static final String USER_VISUALIZATION_MODE = "USER_VISUALIZATION_MODE";
|
public static final String USER_VISUALIZATION_MODE = "USER_VISUALIZATION_MODE";
|
||||||
|
|
||||||
|
private int permissionRequestLatest = 1;
|
||||||
|
private Map<Integer, Runnable> permissionRequestCallbacks = new HashMap<>();
|
||||||
|
|
||||||
CanvasView canvasView;
|
CanvasView canvasView;
|
||||||
com.getbase.floatingactionbutton.AddFloatingActionButton AddPartButton;
|
com.getbase.floatingactionbutton.AddFloatingActionButton AddPartButton;
|
||||||
com.getbase.floatingactionbutton.FloatingActionButton SetDevModeButton;
|
com.getbase.floatingactionbutton.FloatingActionButton SetDevModeButton;
|
||||||
@ -257,4 +265,39 @@ public class CardActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
context.startActivity(i);
|
context.startActivity(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void requestPermissions(String permission, Runnable ifAccepted) {
|
||||||
|
permissionRequestLatest++;
|
||||||
|
int request_code = permissionRequestLatest;
|
||||||
|
permissionRequestCallbacks.put(request_code, ifAccepted);
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
this.requestPermissions(new String[]{permission}, request_code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
|
||||||
|
@NonNull int[] grantResults) {
|
||||||
|
// If request is cancelled, the result arrays are empty.
|
||||||
|
if (grantResults.length > 0 &&
|
||||||
|
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
// Permission is granted. Continue the action or workflow
|
||||||
|
// in your app.
|
||||||
|
if (permissionRequestCallbacks.containsKey(requestCode)) {
|
||||||
|
Runnable callback = permissionRequestCallbacks.get(requestCode);
|
||||||
|
permissionRequestCallbacks.remove(requestCode);
|
||||||
|
callback.run();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO:
|
||||||
|
// Explain to the user that the feature is unavailable because
|
||||||
|
// the features requires a permission that the user has denied.
|
||||||
|
// At the same time, respect the user's decision. Don't link to
|
||||||
|
// system settings in an effort to convince the user to change
|
||||||
|
// their decision.
|
||||||
|
if (permissionRequestCallbacks.containsKey(requestCode)) {
|
||||||
|
permissionRequestCallbacks.remove(requestCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,13 +9,14 @@ import android.util.Log;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.codigoparallevar.minicards.parts.ProgramakerCustomBlockPart;
|
import com.codigoparallevar.minicards.parts.ProgramakerCustomBlockPart;
|
||||||
|
import com.codigoparallevar.minicards.parts.android.CameraStreamer;
|
||||||
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;
|
||||||
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.strings.ConvertToString;
|
import com.codigoparallevar.minicards.parts.strings.ConvertToString;
|
||||||
import com.codigoparallevar.minicards.parts.values.StaticValuePart;
|
import com.codigoparallevar.minicards.parts.values.StaticValuePart;
|
||||||
|
import com.codigoparallevar.minicards.parts.viewers.ImageFrame;
|
||||||
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;
|
||||||
@ -258,8 +259,8 @@ public class CardFile {
|
|||||||
|
|
||||||
return buttonInfo;
|
return buttonInfo;
|
||||||
}
|
}
|
||||||
else if (type.equals(Placeholder.class.getName())) {
|
else if (type.equals(ImageFrame.class.getName())) {
|
||||||
return new Tuple2<>(Placeholder.deserialize(grid, jsonObject.getJSONObject("_data")),
|
return new Tuple2<>(ImageFrame.deserialize(grid, jsonObject.getJSONObject("_data")),
|
||||||
Collections.<PartConnection>emptyList());
|
Collections.<PartConnection>emptyList());
|
||||||
}
|
}
|
||||||
else if (type.equals(ColorBox.class.getName())){
|
else if (type.equals(ColorBox.class.getName())){
|
||||||
@ -301,6 +302,13 @@ public class CardFile {
|
|||||||
|
|
||||||
return staticValuePartInfo;
|
return staticValuePartInfo;
|
||||||
}
|
}
|
||||||
|
else if (type.equals(CameraStreamer.class.getName())){
|
||||||
|
Tuple2<Part, List<PartConnection>> staticValuePartInfo = CameraStreamer.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);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
package com.codigoparallevar.minicards;
|
package com.codigoparallevar.minicards;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Path;
|
import android.graphics.Path;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.codigoparallevar.minicards.types.functional.Tuple2;
|
import com.codigoparallevar.minicards.types.functional.Tuple2;
|
||||||
@ -42,7 +45,6 @@ public class ScrolledCanvas {
|
|||||||
canvas.drawPath(offsetPath, paint);
|
canvas.drawPath(offsetPath, paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void drawCenteredText(String text, int x, int y, Paint paint) {
|
public void drawCenteredText(String text, int x, int y, Paint paint) {
|
||||||
paint.setTextAlign(Paint.Align.LEFT);
|
paint.setTextAlign(Paint.Align.LEFT);
|
||||||
Rect r = new Rect();
|
Rect r = new Rect();
|
||||||
@ -56,4 +58,17 @@ public class ScrolledCanvas {
|
|||||||
public void drawText(String text, int x, int y, Paint paint) {
|
public void drawText(String text, int x, int y, Paint paint) {
|
||||||
canvas.drawText(text, x - xOrig, y - yOrig, paint);
|
canvas.drawText(text, x - xOrig, y - yOrig, paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) {
|
||||||
|
rect.offset(-xOrig, -yOrig);
|
||||||
|
canvas.drawRoundRect(rect, rx, ry, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawBitmap(Bitmap bitmap, Rect rect) {
|
||||||
|
rect.offset(-xOrig, -yOrig);
|
||||||
|
canvas.drawBitmap(bitmap,
|
||||||
|
new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()),
|
||||||
|
rect,
|
||||||
|
null);
|
||||||
|
}
|
||||||
}
|
}
|
@ -3,6 +3,7 @@ package com.codigoparallevar.minicards;
|
|||||||
import com.codigoparallevar.minicards.types.PartGrid;
|
import com.codigoparallevar.minicards.types.PartGrid;
|
||||||
import com.codigoparallevar.minicards.types.Selectable;
|
import com.codigoparallevar.minicards.types.Selectable;
|
||||||
import com.codigoparallevar.minicards.types.connectors.input.AnyInputConnector;
|
import com.codigoparallevar.minicards.types.connectors.input.AnyInputConnector;
|
||||||
|
import com.codigoparallevar.minicards.types.connectors.input.ImageInputConnector;
|
||||||
import com.codigoparallevar.minicards.types.functional.Tuple2;
|
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;
|
||||||
@ -45,6 +46,11 @@ class StubPartGrid implements PartGrid {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ImageInputConnector getImageInputConnectorOn(int xEnd, int yEnd) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tuple2<Integer, Integer> getCenteredOn() {
|
public Tuple2<Integer, Integer> getCenteredOn() {
|
||||||
return null;
|
return null;
|
||||||
|
@ -0,0 +1,458 @@
|
|||||||
|
package com.codigoparallevar.minicards.parts.android;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.ImageFormat;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Path;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.hardware.camera2.CameraAccessException;
|
||||||
|
import android.hardware.camera2.CameraCaptureSession;
|
||||||
|
import android.hardware.camera2.CameraCharacteristics;
|
||||||
|
import android.hardware.camera2.CameraDevice;
|
||||||
|
import android.hardware.camera2.CameraManager;
|
||||||
|
import android.hardware.camera2.CaptureRequest;
|
||||||
|
import android.media.Image;
|
||||||
|
import android.media.ImageReader;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.HandlerThread;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.Surface;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
|
import com.codigoparallevar.minicards.CanvasView;
|
||||||
|
import com.codigoparallevar.minicards.PartInstantiator;
|
||||||
|
import com.codigoparallevar.minicards.ScrolledCanvas;
|
||||||
|
import com.codigoparallevar.minicards.parts.connectors.ImageRoundOutputConnector;
|
||||||
|
import com.codigoparallevar.minicards.parts.style.CardTheme;
|
||||||
|
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.input.InputConnector;
|
||||||
|
import com.codigoparallevar.minicards.types.connectors.output.OutputConnector;
|
||||||
|
import com.codigoparallevar.minicards.types.functional.Tuple2;
|
||||||
|
import com.codigoparallevar.minicards.types.wireData.ImageSignal;
|
||||||
|
import com.codigoparallevar.minicards.types.wireData.WireDataType;
|
||||||
|
import com.codigoparallevar.minicards.utils.Serializations;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
public class CameraStreamer implements Part {
|
||||||
|
private static final String LogTag = "CameraStreamer";
|
||||||
|
|
||||||
|
private static final int DEFAULT_SIDE_SIZE = 200;
|
||||||
|
private final String _id;
|
||||||
|
private final PartGrid _partGrid;
|
||||||
|
private int _left;
|
||||||
|
private int _top;
|
||||||
|
private int _right;
|
||||||
|
private int _bottom;
|
||||||
|
private List<OutputConnector> _outputConnectors;
|
||||||
|
private final ImageRoundOutputConnector _imageRoundOutputConnector;
|
||||||
|
private final long SLEEP_TIME = 1000;
|
||||||
|
private ImageReader imageReader = null;
|
||||||
|
private HandlerThread _thread = null;
|
||||||
|
private Handler _handler = null;
|
||||||
|
|
||||||
|
private CameraStreamer(String id, PartGrid partGrid, int left, int top, int right, int bottom) {
|
||||||
|
_id = id;
|
||||||
|
_partGrid = partGrid;
|
||||||
|
_left = left;
|
||||||
|
_top = top;
|
||||||
|
_right = right;
|
||||||
|
_bottom = bottom;
|
||||||
|
|
||||||
|
// Create connectors
|
||||||
|
_imageRoundOutputConnector = new ImageRoundOutputConnector(
|
||||||
|
this,
|
||||||
|
_partGrid,
|
||||||
|
getOutputConnectorCenterX(), getOutputConnectorCenterY(),
|
||||||
|
getOutputConnectRadius());
|
||||||
|
|
||||||
|
_outputConnectors = new LinkedList<>();
|
||||||
|
_outputConnectors.add(_imageRoundOutputConnector);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public CameraStreamer(PartGrid partGrid, int left, int top, int right, int bottom) {
|
||||||
|
this(UUID.randomUUID().toString(), partGrid, left, top, right, bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void moveEnd(int x, int y) {
|
||||||
|
final int width = _right - _left;
|
||||||
|
final int height = _bottom - _top;
|
||||||
|
|
||||||
|
_left = x - width / 2;
|
||||||
|
_right = _left + width;
|
||||||
|
|
||||||
|
_top = y - height / 2;
|
||||||
|
_bottom = _top + height;
|
||||||
|
|
||||||
|
_imageRoundOutputConnector.updatePosition(
|
||||||
|
getOutputConnectorCenterX(),
|
||||||
|
getOutputConnectorCenterY());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drop(int x, int y) {
|
||||||
|
moveEnd(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsPoint(int x, int y) {
|
||||||
|
return (x >= get_left()) && (x <= get_right())
|
||||||
|
&& (y >= get_top()) && (y <= get_bottom());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Moveable getMoveable() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unlink() {
|
||||||
|
pause();
|
||||||
|
|
||||||
|
for (InputConnector input : getInputConnectors()) {
|
||||||
|
input.unlink();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(ScrolledCanvas canvas, boolean devMode) {
|
||||||
|
if (devMode){
|
||||||
|
drawConnector(canvas);
|
||||||
|
drawWires(canvas, devMode);
|
||||||
|
|
||||||
|
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
paint.setColor(Color.GRAY);
|
||||||
|
|
||||||
|
canvas.drawRect(
|
||||||
|
new Rect(_left, _top,
|
||||||
|
_right, _bottom),
|
||||||
|
paint);
|
||||||
|
|
||||||
|
|
||||||
|
// Draw a little camera
|
||||||
|
Paint iconPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
iconPaint.setStyle(Paint.Style.STROKE);
|
||||||
|
iconPaint.setColor(Color.YELLOW);
|
||||||
|
iconPaint.setStrokeWidth(5f);
|
||||||
|
iconPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||||
|
iconPaint.setStrokeJoin(Paint.Join.ROUND);
|
||||||
|
|
||||||
|
// TODO: Refactor this into something reasonable
|
||||||
|
float side = _right - _left;
|
||||||
|
float mid = side / 2;
|
||||||
|
float quarter = mid / 2;
|
||||||
|
float oct = quarter / 2;
|
||||||
|
float hex = oct / 2;
|
||||||
|
float shex = hex / 2;
|
||||||
|
|
||||||
|
Path path = new Path();
|
||||||
|
// Square top left
|
||||||
|
path.moveTo(_left + oct + hex + shex, _top + quarter + hex);
|
||||||
|
// Square top right
|
||||||
|
path.lineTo(_left + mid + hex + shex, _top + quarter + hex);
|
||||||
|
// Box-to-projection connection
|
||||||
|
path.lineTo(_left + mid + hex + shex, _top + mid);
|
||||||
|
// Projection top right
|
||||||
|
path.lineTo(_right - quarter - hex + hex + shex, _top + quarter + hex);
|
||||||
|
// Projection bottom right
|
||||||
|
path.lineTo(_right - quarter - hex + hex + shex, _bottom - quarter - hex);
|
||||||
|
// Back to box
|
||||||
|
path.lineTo(_left + mid + hex + shex, _top + mid);
|
||||||
|
// Box bottom right
|
||||||
|
path.lineTo(_left + mid + hex + shex, _bottom - quarter - hex);
|
||||||
|
// Box bottom left
|
||||||
|
path.lineTo(_left + oct + hex + shex, _bottom - quarter - hex);
|
||||||
|
|
||||||
|
path.close();
|
||||||
|
canvas.drawPath(path, iconPaint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawConnector(ScrolledCanvas canvas) {
|
||||||
|
Paint outerConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
outerConnectorPaint.setColor(CardTheme.IMAGE_CONNECTOR_COLOR_OUTER);
|
||||||
|
|
||||||
|
canvas.drawCircle(getOutputConnectorCenterX(),
|
||||||
|
getOutputConnectorCenterY(),
|
||||||
|
getOutputConnectRadius(),
|
||||||
|
outerConnectorPaint);
|
||||||
|
|
||||||
|
Paint innerConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
innerConnectorPaint.setColor(CardTheme.IMAGE_CONNECTOR_COLOR_INNER);
|
||||||
|
|
||||||
|
canvas.drawCircle(getOutputConnectorCenterX(),
|
||||||
|
getOutputConnectorCenterY(),
|
||||||
|
getOutputConnectRadius() / 2,
|
||||||
|
innerConnectorPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawWires(ScrolledCanvas canvas, boolean devMode) {
|
||||||
|
for (OutputConnector outputConnector : _outputConnectors){
|
||||||
|
outputConnector.drawWires(canvas, devMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int get_left() {
|
||||||
|
return _left;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int get_right() {
|
||||||
|
return _right;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int get_top() {
|
||||||
|
return _top;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int get_bottom() {
|
||||||
|
return _bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void touched() {
|
||||||
|
// Just ignore it, as it's a logic component
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<InputConnector> getInputConnectors() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<OutputConnector> getOutputConnectors() {
|
||||||
|
return _outputConnectors;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject serialize() throws JSONException {
|
||||||
|
JSONObject serialized = new JSONObject();
|
||||||
|
|
||||||
|
serialized.put("id", _id);
|
||||||
|
serialized.put("left", _left);
|
||||||
|
serialized.put("top", _top);
|
||||||
|
serialized.put("right", _right);
|
||||||
|
serialized.put("bottom", _bottom);
|
||||||
|
serialized.put("on_signal_output_connector",
|
||||||
|
Serializations.serialize(serializeConnectionEndpoints()));
|
||||||
|
|
||||||
|
return serialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Tuple2<Part, List<PartConnection>> deserialize(PartGrid partGrid, JSONObject data) throws JSONException {
|
||||||
|
String id = data.getString("id");
|
||||||
|
int left = data.getInt("left");
|
||||||
|
int top = data.getInt("top");
|
||||||
|
int right = data.getInt("right");
|
||||||
|
int bottom = data.getInt("bottom");
|
||||||
|
|
||||||
|
CameraStreamer cameraStreamer = new CameraStreamer(id, partGrid, left, top, right, bottom);
|
||||||
|
|
||||||
|
List<PartConnection> connections = new LinkedList<>();
|
||||||
|
|
||||||
|
JSONArray connectorOuts = data.getJSONArray("on_signal_output_connector");
|
||||||
|
for (int i = 0; i < connectorOuts.length(); i++){
|
||||||
|
connections.add(PartConnection.deserialize(
|
||||||
|
cameraStreamer._imageRoundOutputConnector,
|
||||||
|
connectorOuts.getJSONObject(i)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Tuple2<Part, List<PartConnection>>(cameraStreamer, connections);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Map<String, String>> serializeConnectionEndpoints() {
|
||||||
|
List<Map<String, String>> serializedData = new LinkedList<>();
|
||||||
|
|
||||||
|
for (Tuple2<String, String> endpoint : _imageRoundOutputConnector.getConnectionEndpoints()){
|
||||||
|
serializedData.add(PartConnection.serialize(endpoint.item1, endpoint.item2));
|
||||||
|
}
|
||||||
|
|
||||||
|
return serializedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void send(InputConnector roundInputConnector, WireDataType signal) {
|
||||||
|
// @TODO: REMOVE THE NEED FOR THIS
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onNewImage(Image img) {
|
||||||
|
_imageRoundOutputConnector.send(new ImageSignal(img));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String get_id() {
|
||||||
|
return _id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputConnector getConnectorWithId(String inputConnectorId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getConnectorId(InputConnector inputConnector) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resume() {
|
||||||
|
if (!(this._partGrid instanceof CanvasView)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CanvasView view = ((CanvasView) this._partGrid);
|
||||||
|
Context ctx = view.getContext();
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
if (ctx.checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
view.requestPermission(Manifest.permission.CAMERA, () -> { CameraStreamer.this.resume(); });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.imageReader = ImageReader.newInstance(100, 100, ImageFormat.JPEG, 30);
|
||||||
|
this.imageReader.setOnImageAvailableListener((ImageReader.OnImageAvailableListener) newImageReader -> {
|
||||||
|
Image latestImage = newImageReader.acquireLatestImage();
|
||||||
|
|
||||||
|
CameraStreamer.this.onNewImage(latestImage);
|
||||||
|
latestImage.close();
|
||||||
|
}, new Handler());
|
||||||
|
|
||||||
|
CameraManager cm = (CameraManager) ctx.getSystemService(Context.CAMERA_SERVICE);
|
||||||
|
try {
|
||||||
|
String[] cameraList = cm.getCameraIdList();
|
||||||
|
for (String cd : cameraList) {
|
||||||
|
//get camera characteristics
|
||||||
|
CameraCharacteristics mCameraCharacteristics = cm.getCameraCharacteristics(cd);
|
||||||
|
|
||||||
|
//check if the camera is in the back - if not, continue to next
|
||||||
|
if (mCameraCharacteristics.get(CameraCharacteristics.LENS_FACING) != CameraCharacteristics.LENS_FACING_BACK) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._thread == null) {
|
||||||
|
this._thread = new HandlerThread("mCameraHandlerThread");
|
||||||
|
this._thread.start();
|
||||||
|
}
|
||||||
|
if (this._handler == null) {
|
||||||
|
this._handler = new Handler(this._thread.getLooper());
|
||||||
|
}
|
||||||
|
|
||||||
|
cm.openCamera(cd, new CameraDevice.StateCallback() {
|
||||||
|
@Override
|
||||||
|
public void onOpened(@NonNull CameraDevice camera) {
|
||||||
|
//make list of surfaces to give to camera
|
||||||
|
List<Surface> surfaceList = new ArrayList<>();
|
||||||
|
Surface surface = CameraStreamer.this.imageReader.getSurface();
|
||||||
|
surfaceList.add(surface);
|
||||||
|
|
||||||
|
try {
|
||||||
|
camera.createCaptureSession(surfaceList, new CameraCaptureSession.StateCallback() {
|
||||||
|
@Override
|
||||||
|
public void onConfigured(@NonNull CameraCaptureSession session) {
|
||||||
|
try {
|
||||||
|
CaptureRequest.Builder requestBuilder = session.getDevice().createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
|
||||||
|
requestBuilder.addTarget(surface);
|
||||||
|
//set to null - image data will be produced but will not receive metadata
|
||||||
|
session.setRepeatingRequest(requestBuilder.build(), null, CameraStreamer.this._handler);
|
||||||
|
} catch (CameraAccessException e) {
|
||||||
|
Log.e(LogTag, "createCaptureSession threw CameraAccessException.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
|
||||||
|
Log.i(LogTag, "Error on camera configuration");
|
||||||
|
}
|
||||||
|
}, CameraStreamer.this._handler);
|
||||||
|
} catch (CameraAccessException e) {
|
||||||
|
Log.e(LogTag, "createCaptureSession threw CameraAccessException.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisconnected(@NonNull CameraDevice camera) {
|
||||||
|
Log.i(LogTag, "Camera disconnected");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(@NonNull CameraDevice camera, int error) {
|
||||||
|
Log.i(LogTag, "Error on camera opening: " + error);
|
||||||
|
}
|
||||||
|
}, this._handler);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (CameraAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pause() {
|
||||||
|
this._handler = null;
|
||||||
|
if (this._thread != null) {
|
||||||
|
this._thread.interrupt();
|
||||||
|
this._thread = null;
|
||||||
|
}
|
||||||
|
if (this.imageReader != null) {
|
||||||
|
this.imageReader.close();
|
||||||
|
this.imageReader = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object query(Object lastValue) {
|
||||||
|
return null; // No relevant value (maybe time?)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private int getOutputConnectorCenterX() {
|
||||||
|
return (_left + _right) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getOutputConnectorCenterY() {
|
||||||
|
return _bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getOutputConnectRadius() {
|
||||||
|
return (_right - _left) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PartInstantiator getInstantiator() {
|
||||||
|
final int halfSideSize = DEFAULT_SIDE_SIZE / 2;
|
||||||
|
return new PartInstantiator() {
|
||||||
|
@Override
|
||||||
|
protected Part instantiate(PartGrid grid, Tuple2<Integer, Integer> center) {
|
||||||
|
return new CameraStreamer(grid,
|
||||||
|
center.item1 - halfSideSize, center.item2 - halfSideSize,
|
||||||
|
center.item1 + halfSideSize, center.item2 + halfSideSize);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,98 @@
|
|||||||
|
package com.codigoparallevar.minicards.parts.connectors;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.codigoparallevar.minicards.types.Moveable;
|
||||||
|
import com.codigoparallevar.minicards.types.Part;
|
||||||
|
import com.codigoparallevar.minicards.types.connectors.Wiring.Wire;
|
||||||
|
import com.codigoparallevar.minicards.types.connectors.input.ImageInputConnector;
|
||||||
|
import com.codigoparallevar.minicards.types.wireData.ImageSignal;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ImageRoundInputConnector implements ImageInputConnector {
|
||||||
|
private final Part _part;
|
||||||
|
private int _xposition;
|
||||||
|
private int _yposition;
|
||||||
|
private final int _radius;
|
||||||
|
private final List<Wire> _attachments = new LinkedList<>();
|
||||||
|
|
||||||
|
public ImageRoundInputConnector(Part part,
|
||||||
|
int inputConnectorCenterX, int inputConnectorCenterY,
|
||||||
|
int inputConnectorRadius) {
|
||||||
|
_part = part;
|
||||||
|
_xposition = inputConnectorCenterX;
|
||||||
|
_yposition = inputConnectorCenterY;
|
||||||
|
_radius = inputConnectorRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsPoint(int x, int y) {
|
||||||
|
return ((Math.abs(x - _xposition) <= _radius)
|
||||||
|
&& (Math.abs(y - _yposition) <= _radius));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Moveable getMoveable() {
|
||||||
|
return new Wire(this, _xposition, _yposition);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unlink() {
|
||||||
|
for (Wire wire : _attachments) {
|
||||||
|
wire.unlink();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updatePosition(int x, int y) {
|
||||||
|
_xposition = x;
|
||||||
|
_yposition = y;
|
||||||
|
|
||||||
|
for (Wire wire : _attachments){
|
||||||
|
wire.moveEnd(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getX() {
|
||||||
|
return _xposition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getY() {
|
||||||
|
return _yposition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void send(ImageSignal signal) {
|
||||||
|
_part.send(this, signal);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addAttachment(Wire<ImageSignal, ImageInputConnector> wire) {
|
||||||
|
_attachments.add(wire);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Part getPart() {
|
||||||
|
return _part;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return _part.getConnectorId(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drop(Wire wire) {
|
||||||
|
Log.d("InputConnector", "Dropped wire " + wire);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void wireUnlinked(Wire wire) {
|
||||||
|
_attachments.remove(wire);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,183 @@
|
|||||||
|
package com.codigoparallevar.minicards.parts.connectors;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.codigoparallevar.minicards.ScrolledCanvas;
|
||||||
|
import com.codigoparallevar.minicards.types.Drawable;
|
||||||
|
import com.codigoparallevar.minicards.types.Moveable;
|
||||||
|
import com.codigoparallevar.minicards.types.Part;
|
||||||
|
import com.codigoparallevar.minicards.types.PartGrid;
|
||||||
|
import com.codigoparallevar.minicards.types.connectors.Wiring.ImageWire;
|
||||||
|
import com.codigoparallevar.minicards.types.connectors.input.ImageInputConnector;
|
||||||
|
import com.codigoparallevar.minicards.types.connectors.input.InputConnector;
|
||||||
|
import com.codigoparallevar.minicards.types.connectors.output.ImageOutputConnector;
|
||||||
|
import com.codigoparallevar.minicards.types.functional.Tuple2;
|
||||||
|
import com.codigoparallevar.minicards.types.wireData.ImageSignal;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ImageRoundOutputConnector implements Drawable, ImageOutputConnector,
|
||||||
|
RoundOutputConnector<ImageSignal, ImageInputConnector, ImageWire> {
|
||||||
|
private static final String LogTag = "ImageRoundOutputConnector";
|
||||||
|
|
||||||
|
private PartGrid _partGrid;
|
||||||
|
private int _centerX;
|
||||||
|
private int _centerY;
|
||||||
|
private final int _radius;
|
||||||
|
private final Part _part;
|
||||||
|
private ImageWire _currentWire = null;
|
||||||
|
private final List<ImageWire> _wires;
|
||||||
|
private final HashSet<InputConnector> _connections;
|
||||||
|
|
||||||
|
public ImageRoundOutputConnector(Part part, PartGrid partGrid, int centerX, int centerY, int radius) {
|
||||||
|
_part = part;
|
||||||
|
_partGrid = partGrid;
|
||||||
|
_centerX = centerX;
|
||||||
|
_centerY = centerY;
|
||||||
|
_radius = radius;
|
||||||
|
_wires = new LinkedList<>();
|
||||||
|
_connections = new HashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsPoint(int x, int y) {
|
||||||
|
return ((Math.abs(x - _centerX) <= _radius)
|
||||||
|
&& (Math.abs(y - _centerY) <= _radius));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Moveable getMoveable() {
|
||||||
|
if (_currentWire == null) {
|
||||||
|
startWire();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _currentWire;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unlink() {}
|
||||||
|
|
||||||
|
private void startWire() {
|
||||||
|
_currentWire = new ImageWire(this, _centerX, _centerY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drop(ImageWire wire) {
|
||||||
|
|
||||||
|
if (wire == _currentWire){
|
||||||
|
_currentWire = null;
|
||||||
|
|
||||||
|
ImageInputConnector resultPoint = _partGrid.getImageInputConnectorOn(
|
||||||
|
wire.getXEnd(), wire.getYEnd());
|
||||||
|
|
||||||
|
Log.d(LogTag, "Dropped wire on " + resultPoint);
|
||||||
|
|
||||||
|
// Not connected
|
||||||
|
if (resultPoint == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Already connected
|
||||||
|
if (_connections.contains(resultPoint)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_connections.add(resultPoint);
|
||||||
|
|
||||||
|
wire.attachTo(resultPoint, this);
|
||||||
|
_wires.add(wire);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Log.w(LogTag,
|
||||||
|
"Asked to drop non matching wire "
|
||||||
|
+ "(expected " + _currentWire + ", got " + wire + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void wireUnlinked(ImageWire wire) {
|
||||||
|
_wires.remove(wire);
|
||||||
|
_connections.remove(wire.getAttachedTo());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawWires(ScrolledCanvas canvas, boolean devMode) {
|
||||||
|
for (ImageWire wire : _wires) {
|
||||||
|
wire.draw(canvas, devMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_currentWire != null) {
|
||||||
|
_currentWire.draw(canvas, devMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updatePosition(int x, int y) {
|
||||||
|
_centerX = x;
|
||||||
|
_centerY = y;
|
||||||
|
|
||||||
|
for (ImageWire wire : _wires){
|
||||||
|
wire.moveStart(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Tuple2<String, String>> getConnectionEndpoints() {
|
||||||
|
List<Tuple2<String, String>> endpointIds = new LinkedList<>();
|
||||||
|
|
||||||
|
for (ImageWire wire : _wires) {
|
||||||
|
InputConnector inputConnector = wire.getAttachedTo();
|
||||||
|
Part endPart = inputConnector.getPart();
|
||||||
|
endpointIds.add(new Tuple2<>(inputConnector.getId(), endPart.get_id()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return endpointIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connectTo(ImageInputConnector inputConnector) {
|
||||||
|
if (_connections.contains(inputConnector)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_connections.add(inputConnector);
|
||||||
|
|
||||||
|
ImageWire wire = new ImageWire(this, _centerX, _centerY);
|
||||||
|
wire.attachTo(inputConnector, this);
|
||||||
|
_wires.add(wire);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(ScrolledCanvas canvas, boolean devMode) {
|
||||||
|
// TODO: Complete this part
|
||||||
|
}
|
||||||
|
|
||||||
|
public void send(ImageSignal signal) {
|
||||||
|
for (ImageWire wire : _wires){
|
||||||
|
wire.send(signal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object query(Object lastValue) {
|
||||||
|
return _part.query(lastValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getX() {
|
||||||
|
return _centerX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getY() {
|
||||||
|
return _centerY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getRadius() {
|
||||||
|
return _radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ImageWire> getWires() {
|
||||||
|
return this._wires;
|
||||||
|
}
|
||||||
|
}
|
@ -125,7 +125,7 @@ public class Ticker implements Part {
|
|||||||
paint);
|
paint);
|
||||||
|
|
||||||
|
|
||||||
// Craw a little clock
|
// Draw a little clock
|
||||||
Paint clockPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
Paint clockPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
clockPaint.setStyle(Paint.Style.STROKE);
|
clockPaint.setStyle(Paint.Style.STROKE);
|
||||||
clockPaint.setColor(Color.YELLOW);
|
clockPaint.setColor(Color.YELLOW);
|
||||||
@ -271,9 +271,7 @@ public class Ticker implements Part {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resume() {
|
public void resume() {
|
||||||
_thread = new Thread(new Runnable() {
|
_thread = new Thread(() -> {
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
while (Ticker.this._thread == Thread.currentThread()) {
|
while (Ticker.this._thread == Thread.currentThread()) {
|
||||||
Ticker.this._signalOutputConnector.send(new Signal());
|
Ticker.this._signalOutputConnector.send(new Signal());
|
||||||
_partGrid.update();
|
_partGrid.update();
|
||||||
@ -286,7 +284,6 @@ public class Ticker implements Part {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
_thread.start();
|
_thread.start();
|
||||||
|
@ -1,189 +0,0 @@
|
|||||||
package com.codigoparallevar.minicards.parts.samples;
|
|
||||||
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.codigoparallevar.minicards.ScrolledCanvas;
|
|
||||||
import com.codigoparallevar.minicards.types.Moveable;
|
|
||||||
import com.codigoparallevar.minicards.types.Part;
|
|
||||||
import com.codigoparallevar.minicards.types.PartGrid;
|
|
||||||
import com.codigoparallevar.minicards.types.connectors.input.InputConnector;
|
|
||||||
import com.codigoparallevar.minicards.types.connectors.output.OutputConnector;
|
|
||||||
import com.codigoparallevar.minicards.types.wireData.WireDataType;
|
|
||||||
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class Placeholder implements Part {
|
|
||||||
private final String _id;
|
|
||||||
private final PartGrid _partGrid;
|
|
||||||
private int _left;
|
|
||||||
private int _top;
|
|
||||||
private int _right;
|
|
||||||
private int _bottom;
|
|
||||||
|
|
||||||
public Placeholder(String id, PartGrid partGrid, int left, int top, int right, int bottom) {
|
|
||||||
_id = id;
|
|
||||||
_partGrid = partGrid;
|
|
||||||
_left = left;
|
|
||||||
_top = top;
|
|
||||||
_right = right;
|
|
||||||
_bottom = bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Placeholder(PartGrid partGrid, int left, int top, int right, int bottom) {
|
|
||||||
this(UUID.randomUUID().toString(), partGrid, left, top, right, bottom);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int get_left() {
|
|
||||||
return _left;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int get_right() {
|
|
||||||
return _right;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int get_top() {
|
|
||||||
return _top;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int get_bottom() {
|
|
||||||
return _bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void draw(ScrolledCanvas canvas, boolean devMode) {
|
|
||||||
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
|
||||||
paint.setColor(Color.WHITE);
|
|
||||||
|
|
||||||
// Top
|
|
||||||
canvas.drawLine(_left, _top, _right, _top, paint);
|
|
||||||
// Bottom
|
|
||||||
canvas.drawLine(_left, _bottom, _right, _bottom, paint);
|
|
||||||
// Left
|
|
||||||
canvas.drawLine(_left, _top, _left, _bottom, paint);
|
|
||||||
// Right
|
|
||||||
canvas.drawLine(_right, _top, _right, _bottom, paint);
|
|
||||||
// Cross, top-left, bottom-right
|
|
||||||
canvas.drawLine(_left, _top, _right, _bottom, paint);
|
|
||||||
// Cross, top-right, bottom-left
|
|
||||||
canvas.drawLine(_right, _top, _left, _bottom, paint);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void moveEnd(int x, int y) {
|
|
||||||
final int width = _right - _left;
|
|
||||||
final int height = _bottom - _top;
|
|
||||||
|
|
||||||
_left = x - width / 2;
|
|
||||||
_right = _left + width;
|
|
||||||
|
|
||||||
_top = y - height / 2;
|
|
||||||
_bottom = _top + height;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void drop(int x, int y) {
|
|
||||||
moveEnd(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void touched() {
|
|
||||||
Log.d("Placeholder", "Placeholder touched");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<InputConnector> getInputConnectors() {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<OutputConnector> getOutputConnectors() {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JSONObject serialize() throws JSONException {
|
|
||||||
JSONObject serialized = new JSONObject();
|
|
||||||
|
|
||||||
serialized.put("id", _id);
|
|
||||||
serialized.put("left", _left);
|
|
||||||
serialized.put("top", _top);
|
|
||||||
serialized.put("right", _right);
|
|
||||||
serialized.put("bottom", _bottom);
|
|
||||||
|
|
||||||
return serialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void send(InputConnector roundInputConnector, WireDataType signal) {
|
|
||||||
// @TODO: REMOVE THE NEED FOR THIS
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String get_id() {
|
|
||||||
return _id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputConnector getConnectorWithId(String inputConnectorId) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getConnectorId(InputConnector inputConnector) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void resume() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pause() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object query(Object lastValue) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Part deserialize(PartGrid partGrid, JSONObject data) throws JSONException {
|
|
||||||
String id = data.getString("id");
|
|
||||||
int left = data.getInt("left");
|
|
||||||
int top = data.getInt("top");
|
|
||||||
int right = data.getInt("right");
|
|
||||||
int bottom = data.getInt("bottom");
|
|
||||||
|
|
||||||
return new Placeholder(id, partGrid, left, top, right, bottom);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean containsPoint(int x, int y) {
|
|
||||||
return (x >= get_left()) && (x <= get_right())
|
|
||||||
&& (y >= get_top()) && (y <= get_bottom());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Moveable getMoveable() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unlink() {
|
|
||||||
for (InputConnector input : getInputConnectors()) {
|
|
||||||
input.unlink();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -28,4 +28,7 @@ public class CardTheme {
|
|||||||
|
|
||||||
public static final int UNKNOWN_CONNECTOR_COLOR_OUTER = Color.parseColor("#7f7f7f");
|
public static final int UNKNOWN_CONNECTOR_COLOR_OUTER = Color.parseColor("#7f7f7f");
|
||||||
public static final int UNKNOWN_CONNECTOR_COLOR_INNER = DEFAULT_COLOR_INNER;
|
public static final int UNKNOWN_CONNECTOR_COLOR_INNER = DEFAULT_COLOR_INNER;
|
||||||
|
|
||||||
|
public static final int IMAGE_CONNECTOR_COLOR_OUTER = Color.parseColor("#007700");
|
||||||
|
public static final int IMAGE_CONNECTOR_COLOR_INNER = DEFAULT_COLOR_INNER;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,316 @@
|
|||||||
|
package com.codigoparallevar.minicards.parts.viewers;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.ImageFormat;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
import android.media.Image;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.codigoparallevar.minicards.PartInstantiator;
|
||||||
|
import com.codigoparallevar.minicards.ScrolledCanvas;
|
||||||
|
import com.codigoparallevar.minicards.parts.connectors.ImageRoundInputConnector;
|
||||||
|
import com.codigoparallevar.minicards.parts.style.CardTheme;
|
||||||
|
import com.codigoparallevar.minicards.types.Moveable;
|
||||||
|
import com.codigoparallevar.minicards.types.Part;
|
||||||
|
import com.codigoparallevar.minicards.types.PartGrid;
|
||||||
|
import com.codigoparallevar.minicards.types.connectors.input.ImageInputConnector;
|
||||||
|
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.ImageSignal;
|
||||||
|
import com.codigoparallevar.minicards.types.wireData.WireDataType;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class ImageFrame implements Part {
|
||||||
|
private static final String LogTag = "ImageFrame";
|
||||||
|
private static final int DEFAULT_SIDE_SIZE = 400;
|
||||||
|
private static final String IMAGE_INPUT_CONNECTOR_ID = "image_input_connector";
|
||||||
|
|
||||||
|
private final String _id;
|
||||||
|
private final PartGrid _partGrid;
|
||||||
|
private int _left;
|
||||||
|
private int _top;
|
||||||
|
private int _right;
|
||||||
|
private int _bottom;
|
||||||
|
private List<InputConnector> inputConnectors;
|
||||||
|
private ImageInputConnector _imageInputConnector;
|
||||||
|
private Bitmap lastImage;
|
||||||
|
|
||||||
|
public ImageFrame(String id, PartGrid partGrid, int left, int top, int right, int bottom) {
|
||||||
|
_id = id;
|
||||||
|
_partGrid = partGrid;
|
||||||
|
_left = left;
|
||||||
|
_top = top;
|
||||||
|
_right = right;
|
||||||
|
_bottom = bottom;
|
||||||
|
|
||||||
|
_imageInputConnector = new ImageRoundInputConnector(
|
||||||
|
this,
|
||||||
|
getInputConnectorCenterX(),
|
||||||
|
getInputConnectorCenterY(),
|
||||||
|
getInputConnectRadius());
|
||||||
|
inputConnectors = new LinkedList<>();
|
||||||
|
inputConnectors.add(_imageInputConnector);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImageFrame(PartGrid partGrid, int left, int top, int right, int bottom) {
|
||||||
|
this(UUID.randomUUID().toString(), partGrid, left, top, right, bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int get_left() {
|
||||||
|
return _left;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int get_right() {
|
||||||
|
return _right;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int get_top() {
|
||||||
|
return _top;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int get_bottom() {
|
||||||
|
return _bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(ScrolledCanvas canvas, boolean devMode) {
|
||||||
|
if (devMode){
|
||||||
|
drawConnector(canvas);
|
||||||
|
// drawWires(canvas, devMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect frameRect = new Rect(_left, _top, _right, _bottom);
|
||||||
|
if (this.lastImage == null) {
|
||||||
|
Paint backdropPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
backdropPaint.setColor(Color.parseColor("#444444"));
|
||||||
|
|
||||||
|
canvas.drawRoundRect(new RectF(frameRect), 50, 50, backdropPaint);
|
||||||
|
|
||||||
|
Paint crossPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
crossPaint.setColor(Color.WHITE);
|
||||||
|
|
||||||
|
// Top
|
||||||
|
canvas.drawLine(_left, _top, _right, _top, crossPaint);
|
||||||
|
// Bottom
|
||||||
|
canvas.drawLine(_left, _bottom, _right, _bottom, crossPaint);
|
||||||
|
// Left
|
||||||
|
canvas.drawLine(_left, _top, _left, _bottom, crossPaint);
|
||||||
|
// Right
|
||||||
|
canvas.drawLine(_right, _top, _right, _bottom, crossPaint);
|
||||||
|
// Cross, top-left, bottom-right
|
||||||
|
canvas.drawLine(_left, _top, _right, _bottom, crossPaint);
|
||||||
|
// Cross, top-right, bottom-left
|
||||||
|
canvas.drawLine(_right, _top, _left, _bottom, crossPaint);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
canvas.drawBitmap(this.lastImage, frameRect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawConnector(ScrolledCanvas canvas) {
|
||||||
|
Paint outerInputConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
outerInputConnectorPaint.setColor(CardTheme.IMAGE_CONNECTOR_COLOR_OUTER);
|
||||||
|
|
||||||
|
canvas.drawCircle(
|
||||||
|
getInputConnectorCenterX(),
|
||||||
|
getInputConnectorCenterY(),
|
||||||
|
getInputConnectRadius(),
|
||||||
|
outerInputConnectorPaint);
|
||||||
|
|
||||||
|
Paint innerInputConnectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
innerInputConnectorPaint.setColor(CardTheme.IMAGE_CONNECTOR_COLOR_INNER);
|
||||||
|
|
||||||
|
canvas.drawCircle(
|
||||||
|
getInputConnectorCenterX(),
|
||||||
|
getInputConnectorCenterY(),
|
||||||
|
getInputConnectRadius() / 2,
|
||||||
|
innerInputConnectorPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void moveEnd(int x, int y) {
|
||||||
|
final int width = _right - _left;
|
||||||
|
final int height = _bottom - _top;
|
||||||
|
|
||||||
|
_left = x - width / 2;
|
||||||
|
_right = _left + width;
|
||||||
|
|
||||||
|
_top = y - height / 2;
|
||||||
|
_bottom = _top + height;
|
||||||
|
|
||||||
|
_imageInputConnector.updatePosition(
|
||||||
|
getInputConnectorCenterX(),
|
||||||
|
getInputConnectorCenterY());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drop(int x, int y) {
|
||||||
|
moveEnd(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void touched() {
|
||||||
|
Log.d(LogTag, "Touched");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<InputConnector> getInputConnectors() {
|
||||||
|
return inputConnectors;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<OutputConnector> getOutputConnectors() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject serialize() throws JSONException {
|
||||||
|
JSONObject serialized = new JSONObject();
|
||||||
|
|
||||||
|
serialized.put("id", _id);
|
||||||
|
serialized.put("left", _left);
|
||||||
|
serialized.put("top", _top);
|
||||||
|
serialized.put("right", _right);
|
||||||
|
serialized.put("bottom", _bottom);
|
||||||
|
|
||||||
|
return serialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void send(InputConnector roundInputConnector, WireDataType signal) {
|
||||||
|
if (!(signal instanceof ImageSignal)) {
|
||||||
|
Log.e(LogTag, "Mismatched type, expected {ImageSignal}, found {" + signal + "}" );
|
||||||
|
}
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
|
||||||
|
// No way to get the format?
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageSignal imgSignal = (ImageSignal) signal;
|
||||||
|
Image image = imgSignal.get();
|
||||||
|
if (image.getFormat() == ImageFormat.JPEG) {
|
||||||
|
Image.Plane[] planes = image.getPlanes();
|
||||||
|
if (planes.length != 1) {
|
||||||
|
// TODO: Handle this case (what would it mean?)
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteBuffer jpegBuffer = planes[0].getBuffer();
|
||||||
|
byte[] jpegData = new byte[jpegBuffer.remaining()];
|
||||||
|
jpegBuffer.get(jpegData);
|
||||||
|
|
||||||
|
Bitmap bitmap = BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length);
|
||||||
|
this.lastImage = bitmap;
|
||||||
|
this._partGrid.update(); // Maybe this can be avoided? Directly copying the data on the canvas?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String get_id() {
|
||||||
|
return _id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputConnector getConnectorWithId(String inputConnectorId) {
|
||||||
|
switch (inputConnectorId){
|
||||||
|
case ImageFrame.IMAGE_INPUT_CONNECTOR_ID:
|
||||||
|
return _imageInputConnector;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getConnectorId(InputConnector inputConnector) {
|
||||||
|
if (inputConnector == _imageInputConnector){
|
||||||
|
return ImageFrame.IMAGE_INPUT_CONNECTOR_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void resume() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pause() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object query(Object lastValue) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Part deserialize(PartGrid partGrid, JSONObject data) throws JSONException {
|
||||||
|
String id = data.getString("id");
|
||||||
|
int left = data.getInt("left");
|
||||||
|
int top = data.getInt("top");
|
||||||
|
int right = data.getInt("right");
|
||||||
|
int bottom = data.getInt("bottom");
|
||||||
|
|
||||||
|
return new ImageFrame(id, partGrid, left, top, right, bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsPoint(int x, int y) {
|
||||||
|
return (x >= get_left()) && (x <= get_right())
|
||||||
|
&& (y >= get_top()) && (y <= get_bottom());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Moveable getMoveable() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unlink() {
|
||||||
|
for (InputConnector input : getInputConnectors()) {
|
||||||
|
input.unlink();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInputConnectorCenterX() {
|
||||||
|
return (get_left() + get_right()) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getInputConnectRadius() {
|
||||||
|
return (get_right() - get_left()) / 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInputConnectorCenterY() {
|
||||||
|
return get_top();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PartInstantiator getInstantiator() {
|
||||||
|
final int halfSideSize = DEFAULT_SIDE_SIZE / 2;
|
||||||
|
return new PartInstantiator() {
|
||||||
|
@Override
|
||||||
|
protected Part instantiate(PartGrid grid, Tuple2<Integer, Integer> center) {
|
||||||
|
return new ImageFrame(grid,
|
||||||
|
center.item1 - halfSideSize, center.item2 - halfSideSize,
|
||||||
|
center.item1 + halfSideSize, center.item2 + halfSideSize);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,7 @@ import com.codigoparallevar.minicards.types.PartGrid;
|
|||||||
import com.codigoparallevar.minicards.types.Selectable;
|
import com.codigoparallevar.minicards.types.Selectable;
|
||||||
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.ImageInputConnector;
|
||||||
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;
|
||||||
@ -83,6 +84,11 @@ class PartShowcaseView extends View implements PartGrid {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ImageInputConnector getImageInputConnectorOn(int xEnd, int yEnd) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tuple2<Integer, Integer> getCenteredOn() {
|
public Tuple2<Integer, Integer> getCenteredOn() {
|
||||||
return center;
|
return center;
|
||||||
|
@ -15,11 +15,13 @@ import androidx.appcompat.app.AlertDialog;
|
|||||||
|
|
||||||
import com.codigoparallevar.minicards.CanvasView;
|
import com.codigoparallevar.minicards.CanvasView;
|
||||||
import com.codigoparallevar.minicards.PartInstantiator;
|
import com.codigoparallevar.minicards.PartInstantiator;
|
||||||
|
import com.codigoparallevar.minicards.parts.android.CameraStreamer;
|
||||||
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;
|
||||||
import com.codigoparallevar.minicards.parts.samples.ColorBox;
|
import com.codigoparallevar.minicards.parts.samples.ColorBox;
|
||||||
import com.codigoparallevar.minicards.parts.strings.ConvertToString;
|
import com.codigoparallevar.minicards.parts.strings.ConvertToString;
|
||||||
|
import com.codigoparallevar.minicards.parts.viewers.ImageFrame;
|
||||||
import com.codigoparallevar.minicards.types.Part;
|
import com.codigoparallevar.minicards.types.Part;
|
||||||
import com.codigoparallevar.minicards.types.functional.Consumer;
|
import com.codigoparallevar.minicards.types.functional.Consumer;
|
||||||
import com.codigoparallevar.minicards.types.functional.Tuple2;
|
import com.codigoparallevar.minicards.types.functional.Tuple2;
|
||||||
@ -37,18 +39,37 @@ import java.util.Vector;
|
|||||||
public class PartsHolder {
|
public class PartsHolder {
|
||||||
private final Context context;
|
private final Context context;
|
||||||
|
|
||||||
private final static List<Tuple2<String, PartInstantiator>> BuiltInParts =
|
private final static List<Tuple2<String, PartInstantiator>> GuiParts =
|
||||||
new Vector<Tuple2<String, PartInstantiator>>(){{
|
new Vector<Tuple2<String, PartInstantiator>>(){{
|
||||||
add(new Tuple2<>("Round button", RoundButton.getInstantiator()));
|
add(new Tuple2<>("Round button", RoundButton.getInstantiator()));
|
||||||
add(new Tuple2<>("Ticker", Ticker.getInstantiator()));
|
|
||||||
add(new Tuple2<>("Red/Green box", ColorBox.getInstantiator()));
|
add(new Tuple2<>("Red/Green box", ColorBox.getInstantiator()));
|
||||||
|
add(new Tuple2<>("Image frame", ImageFrame.getInstantiator()));
|
||||||
|
}};
|
||||||
|
|
||||||
|
private final static List<Tuple2<String, PartInstantiator>> AndroidParts =
|
||||||
|
new Vector<Tuple2<String, PartInstantiator>>(){{
|
||||||
|
add(new Tuple2<>("Camera", CameraStreamer.getInstantiator()));
|
||||||
|
}};
|
||||||
|
|
||||||
|
private final static List<Tuple2<String, PartInstantiator>> MiscParts =
|
||||||
|
new Vector<Tuple2<String, PartInstantiator>>(){{
|
||||||
|
add(new Tuple2<>("Ticker", Ticker.getInstantiator()));
|
||||||
add(new Tuple2<>("Toggle", Toggle.getInstantiator()));
|
add(new Tuple2<>("Toggle", Toggle.getInstantiator()));
|
||||||
|
}};
|
||||||
|
|
||||||
|
private final static List<Tuple2<String, PartInstantiator>> DebuggingParts =
|
||||||
|
new Vector<Tuple2<String, PartInstantiator>>(){{
|
||||||
add(new Tuple2<>("ToString", ConvertToString.getInstantiator()));
|
add(new Tuple2<>("ToString", ConvertToString.getInstantiator()));
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|
||||||
private final List<PartCategory> Categories = new Vector<PartCategory>() {{
|
private final List<PartCategory> Categories = new Vector<PartCategory>() {{
|
||||||
add(new PartCategory("Testing", BuiltInParts));
|
add(new PartCategory("GUI elements", GuiParts));
|
||||||
|
add(new PartCategory("Android", AndroidParts));
|
||||||
|
add(new PartCategory("Misc", MiscParts));
|
||||||
|
add(new PartCategory("Debugging", DebuggingParts));
|
||||||
}};
|
}};
|
||||||
|
|
||||||
private Map<String, ProgramakerBridgeInfo> bridgeInfoMap;
|
private Map<String, ProgramakerBridgeInfo> bridgeInfoMap;
|
||||||
private final static String LogTag = "PartsHolder";
|
private final static String LogTag = "PartsHolder";
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package com.codigoparallevar.minicards.types;
|
|||||||
import com.codigoparallevar.minicards.SignalListenerManager;
|
import com.codigoparallevar.minicards.SignalListenerManager;
|
||||||
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.ImageInputConnector;
|
||||||
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;
|
||||||
@ -17,9 +18,9 @@ public interface PartGrid {
|
|||||||
BooleanInputConnector getBooleanInputConnectorOn(int x, int y);
|
BooleanInputConnector getBooleanInputConnectorOn(int x, int y);
|
||||||
AnyInputConnector getAnyInputConnectorOn(int x, int y);
|
AnyInputConnector getAnyInputConnectorOn(int x, int y);
|
||||||
StringInputConnector getStringInputConnectorOn(int xEnd, int yEnd);
|
StringInputConnector getStringInputConnectorOn(int xEnd, int yEnd);
|
||||||
|
ImageInputConnector getImageInputConnectorOn(int xEnd, int yEnd);
|
||||||
|
|
||||||
Tuple2<Integer,Integer> getCenteredOn();
|
Tuple2<Integer,Integer> getCenteredOn();
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.codigoparallevar.minicards.types.connectors.Wiring;
|
||||||
|
|
||||||
|
import com.codigoparallevar.minicards.types.Drawable;
|
||||||
|
import com.codigoparallevar.minicards.types.Moveable;
|
||||||
|
import com.codigoparallevar.minicards.types.connectors.input.ImageInputConnector;
|
||||||
|
import com.codigoparallevar.minicards.types.connectors.output.OutputConnector;
|
||||||
|
import com.codigoparallevar.minicards.types.wireData.ImageSignal;
|
||||||
|
|
||||||
|
public class ImageWire extends Wire<ImageSignal, ImageInputConnector> implements Moveable, Drawable {
|
||||||
|
public ImageWire(OutputConnector dropper, int xInit, int yInit) {
|
||||||
|
super(dropper, xInit, yInit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void send(ImageSignal signal) {
|
||||||
|
if (_attachedTo != null) {
|
||||||
|
_attachedTo.send(signal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package com.codigoparallevar.minicards.types.connectors.input;
|
||||||
|
|
||||||
|
import com.codigoparallevar.minicards.types.wireData.ImageSignal;
|
||||||
|
|
||||||
|
public interface ImageInputConnector extends InputConnector<ImageSignal, ImageInputConnector> {
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.codigoparallevar.minicards.types.connectors.output;
|
||||||
|
|
||||||
|
import com.codigoparallevar.minicards.types.connectors.Wiring.ImageWire;
|
||||||
|
import com.codigoparallevar.minicards.types.connectors.input.ImageInputConnector;
|
||||||
|
import com.codigoparallevar.minicards.types.wireData.ImageSignal;
|
||||||
|
|
||||||
|
public interface ImageOutputConnector extends OutputConnector<
|
||||||
|
ImageSignal,
|
||||||
|
ImageInputConnector,
|
||||||
|
ImageWire> {
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.codigoparallevar.minicards.types.wireData;
|
||||||
|
|
||||||
|
import android.media.Image;
|
||||||
|
|
||||||
|
public class ImageSignal implements WireDataType<Image> {
|
||||||
|
public final Image value;
|
||||||
|
|
||||||
|
public ImageSignal(Image value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Image get() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user