diff --git a/app/src/main/java/com/codigoparallevar/minicards/PartCanvasView.java b/app/src/main/java/com/codigoparallevar/minicards/PartCanvasView.java index 42b204d..fce5cb6 100644 --- a/app/src/main/java/com/codigoparallevar/minicards/PartCanvasView.java +++ b/app/src/main/java/com/codigoparallevar/minicards/PartCanvasView.java @@ -16,6 +16,18 @@ import com.codigoparallevar.minicards.parts.Placeholder; import com.codigoparallevar.minicards.parts.buttons.RoundButton; import com.codigoparallevar.minicards.parts.types.Position; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; import java.util.ArrayList; class PartCanvasView extends View { @@ -35,13 +47,62 @@ class PartCanvasView extends View { @Nullable private MotionMode.Type motionMode; + @NonNull + private String name = "default"; private final static float touchTimeForLongTouchInMillis = 500; public PartCanvasView(Context context) { super(context); this.setBackgroundColor(Color.rgb(4, 69, 99)); - parts.add(new Placeholder(50, 50, 750, 500)); - parts.add(new RoundButton(500, 1200, 80, 100)); + + if (!loadState()){ + parts.add(new Placeholder(50, 50, 750, 500)); + parts.add(new RoundButton(500, 1200, 80, 100)); + } + } + + private boolean loadState(){ + File filesDir = getContext().getFilesDir(); + File file = new File(filesDir + "/" + name); + FileReader fileIn = null; + try { + fileIn = new FileReader(file); + char[] data = new char[(int) file.length()]; + fileIn.read(data); + JSONArray jsonParts = new JSONArray(new String(data )); + for (int i = 0; i < jsonParts.length(); i++){ + deserializeObject(jsonParts.getJSONObject(i)); + } + } catch (IOException e) { + parts.clear(); + Log.w("PartCanvasView", e.getMessage()); + return false; + } catch (JSONException e) { + parts.clear(); + Log.w("PartCanvasView", e.getMessage()); + return false; + } + + try { + fileIn.close(); + } catch (IOException e) { + Log.w("PartCanvasView", e.getMessage()); + return false; + } + return true; + } + + private void deserializeObject(JSONObject jsonObject) throws JSONException { + String type = jsonObject.getString("_type"); + if(type.equals(RoundButton.class.getName())) { + parts.add(RoundButton.deserialize(jsonObject.getJSONObject("_data"))); + } + else if (type.equals(Placeholder.class.getName())) { + parts.add(Placeholder.deserialize(jsonObject.getJSONObject("_data"))); + } + else { + throw new JSONException("Expected known class, found " + type); + } } @Override @@ -110,6 +171,11 @@ class PartCanvasView extends View { motionMode = null; selectedPart = null; } + try { + saveState(); + } catch (IOException e) { + Log.w("PartCanvasView", e.getMessage()); + } break; case MotionEvent.ACTION_MOVE: @@ -137,6 +203,33 @@ class PartCanvasView extends View { return true; } + private void saveState() throws IOException { + File filesDir = getContext().getFilesDir(); + FileOutputStream fileOut = new FileOutputStream(filesDir + "/" + name); + + byte[] serialized = serializeState(); + fileOut.write(serialized); + + fileOut.close(); + } + + private byte[] serializeState() throws IOException { + JSONArray partArray = new JSONArray(); + for (Part part : parts) { + JSONObject serializedPart = new JSONObject(); + try { + serializedPart.put("_type", part.getClass().getName()); + serializedPart.put("_data", part.serialize()); + } catch (JSONException e) { + throw new IOException(e.getMessage(), e.getCause()); + } + + partArray.put(serializedPart); + } + + return partArray.toString().getBytes("UTF-8"); + } + @Nullable private MotionMode.Type getMotionMode(boolean canWait) { if (selectedPart == null){ diff --git a/app/src/main/java/com/codigoparallevar/minicards/parts/Part.java b/app/src/main/java/com/codigoparallevar/minicards/parts/Part.java index ad06036..ee6c46d 100644 --- a/app/src/main/java/com/codigoparallevar/minicards/parts/Part.java +++ b/app/src/main/java/com/codigoparallevar/minicards/parts/Part.java @@ -2,6 +2,9 @@ package com.codigoparallevar.minicards.parts; import android.graphics.Canvas; +import org.json.JSONException; +import org.json.JSONObject; + public interface Part { int getLeft(); int getRight(); @@ -13,4 +16,6 @@ public interface Part { void move(int x, int y); void touched(); + + JSONObject serialize() throws JSONException; } diff --git a/app/src/main/java/com/codigoparallevar/minicards/parts/Placeholder.java b/app/src/main/java/com/codigoparallevar/minicards/parts/Placeholder.java index 8b0ae48..1cae278 100644 --- a/app/src/main/java/com/codigoparallevar/minicards/parts/Placeholder.java +++ b/app/src/main/java/com/codigoparallevar/minicards/parts/Placeholder.java @@ -5,6 +5,9 @@ import android.graphics.Color; import android.graphics.Paint; import android.util.Log; +import org.json.JSONException; +import org.json.JSONObject; + public class Placeholder implements Part { private int _left; private int _top; @@ -73,4 +76,25 @@ public class Placeholder implements Part { public void touched() { Log.d("Placeholder", "Placeholder touched"); } + + @Override + public JSONObject serialize() throws JSONException { + JSONObject serialized = new JSONObject(); + + serialized.put("left", _left); + serialized.put("top", _top); + serialized.put("right", _right); + serialized.put("bottom", _bottom); + + return serialized; + } + + public static Part deserialize(JSONObject data) throws JSONException { + int left = data.getInt("left"); + int top = data.getInt("top"); + int right = data.getInt("right"); + int bottom = data.getInt("bottom"); + + return new Placeholder(left, top, right, bottom); + } } diff --git a/app/src/main/java/com/codigoparallevar/minicards/parts/buttons/RoundButton.java b/app/src/main/java/com/codigoparallevar/minicards/parts/buttons/RoundButton.java index 4cdbdb3..621fe46 100644 --- a/app/src/main/java/com/codigoparallevar/minicards/parts/buttons/RoundButton.java +++ b/app/src/main/java/com/codigoparallevar/minicards/parts/buttons/RoundButton.java @@ -7,6 +7,9 @@ import android.util.Log; import com.codigoparallevar.minicards.parts.Part; +import org.json.JSONException; +import org.json.JSONObject; + public class RoundButton implements Part { @@ -66,4 +69,27 @@ public class RoundButton implements Part { public void touched() { Log.d("RoundButton", "Round button touched"); } + + @Override + public JSONObject serialize() throws JSONException { + JSONObject serialized = new JSONObject(); + + serialized.put("x_center", _xCenter); + serialized.put("y_center", _yCenter); + serialized.put("inner_radius", _innerRadius); + serialized.put("outer_radius", _outerRadius); + serialized.put("outer_radius_thickness", _outerRadiusThickness); + + return serialized; + } + + public static Part deserialize(JSONObject data) throws JSONException { + int xCenter = data.getInt("x_center"); + int yCenter = data.getInt("y_center"); + + int innerRadius = data.getInt("inner_radius"); + int outerRadius = data.getInt("outer_radius"); + + return new RoundButton(xCenter, yCenter, innerRadius, outerRadius); + } }