/* * Copyright (C) 2016 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.android.apps.santatracker.doodles.tilt; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Cap; import android.graphics.Paint.Style; import com.google.android.apps.santatracker.doodles.shared.Actor; import com.google.android.apps.santatracker.doodles.shared.Vector2D; import com.google.android.apps.santatracker.doodles.shared.physics.Util; import org.json.JSONException; import org.json.JSONObject; import java.util.HashMap; import java.util.Map; /** * An actor class which represents an arbitrarily-colored rectangle. */ public class ColoredRectangleActor extends Actor implements Touchable { /* Default color is black*/ public static final String UNSPECIFIED = "unspecified"; /* Golf colors */ public static final String TEE_GREEN = "tee"; public static final String FAIRWAY_GREEN = "fairway"; /* Swimming colors */ public static final String DISTANCE_30M = "30m"; public static final String DISTANCE_50M = "50m"; public static final String DISTANCE_100M = "100m"; public static final String DISTANCE_LEVEL_LENGTH = "level length"; public static final String DISTANCE_PR = "pr"; public static final String STARTING_BLOCK = "start"; public static final String DIMENS_X_KEY = "dimens x"; public static final String DIMENS_Y_KEY = "dimens y"; public static final Map<String, Integer> TYPE_TO_COLOR_MAP; static { TYPE_TO_COLOR_MAP = new HashMap<>(); /* Golf */ TYPE_TO_COLOR_MAP.put(TEE_GREEN, Constants.LIGHT_GREEN); TYPE_TO_COLOR_MAP.put(FAIRWAY_GREEN, Constants.DARK_GREEN); /* Swimming */ TYPE_TO_COLOR_MAP.put(DISTANCE_30M, 0x44cd7f32); TYPE_TO_COLOR_MAP.put(DISTANCE_50M, 0x44c0c0c0); TYPE_TO_COLOR_MAP.put(DISTANCE_100M, 0x44ffd700); TYPE_TO_COLOR_MAP.put(DISTANCE_LEVEL_LENGTH, 0x44ffffff); TYPE_TO_COLOR_MAP.put(DISTANCE_PR, 0x4400cc00); TYPE_TO_COLOR_MAP.put(STARTING_BLOCK, 0xff4993a4); TYPE_TO_COLOR_MAP.put(UNSPECIFIED, 0xff000000); } /** * A direction used to pull the boundaries of the colored rectangle. */ private enum Direction { NONE, UP, DOWN, LEFT, RIGHT, } private Direction selectedDirection; public String type; public Vector2D dimens; private Paint paint; private Paint midpointPaint; private Vector2D upMidpoint = Vector2D.get(); private Vector2D downMidpoint = Vector2D.get(); private Vector2D leftMidpoint = Vector2D.get(); private Vector2D rightMidpoint = Vector2D.get(); public ColoredRectangleActor(Vector2D position, Vector2D dimens) { this(position, dimens, UNSPECIFIED); } public ColoredRectangleActor(Vector2D position, Vector2D dimens, String type) { super(position, Vector2D.get()); this.dimens = dimens; this.type = type; this.zIndex = -1; if (type.equals(FAIRWAY_GREEN)) { this.zIndex = -2; } selectedDirection = Direction.NONE; paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(TYPE_TO_COLOR_MAP.get(type)); paint.setStyle(Style.FILL); midpointPaint = new Paint(Paint.ANTI_ALIAS_FLAG); midpointPaint.setColor(Color.WHITE); updateExtents(); } @Override public void draw(Canvas canvas) { canvas.drawRect(position.x, position.y, position.x + dimens.x, position.y + dimens.y, paint); } public void setStyle(Style style) { paint.setStyle(style); } public void setStrokeWidth(float width) { paint.setStrokeWidth(width); paint.setStrokeCap(Cap.ROUND); } public void setColor(int color) { paint.setColor(color); } @Override public String getType() { return type; } @Override public boolean canHandleTouchAt(Vector2D worldCoords, float cameraScale) { Vector2D lowerRight = Vector2D.get(position).add(dimens); boolean retVal = Util.pointIsWithinBounds(position, lowerRight, worldCoords) || worldCoords.distanceTo(upMidpoint) < Constants.SELECTION_RADIUS || worldCoords.distanceTo(downMidpoint) < Constants.SELECTION_RADIUS || worldCoords.distanceTo(leftMidpoint) < Constants.SELECTION_RADIUS || worldCoords.distanceTo(rightMidpoint) < Constants.SELECTION_RADIUS; lowerRight.release(); return retVal; } @Override public void startTouchAt(Vector2D worldCoords, float cameraScale) { if (worldCoords.distanceTo(upMidpoint) < Constants.SELECTION_RADIUS) { selectedDirection = Direction.UP; } else if (worldCoords.distanceTo(downMidpoint) < Constants.SELECTION_RADIUS) { selectedDirection = Direction.DOWN; } else if (worldCoords.distanceTo(leftMidpoint) < Constants.SELECTION_RADIUS) { selectedDirection = Direction.LEFT; } else if (worldCoords.distanceTo(rightMidpoint) < Constants.SELECTION_RADIUS) { selectedDirection = Direction.RIGHT; } else { selectedDirection = Direction.NONE; } } @Override public boolean handleMoveEvent(Vector2D delta) { if (selectedDirection == Direction.NONE) { position.subtract(delta); } else if (selectedDirection == Direction.UP) { position.y -= delta.y; dimens.y += delta.y; } else if (selectedDirection == Direction.DOWN) { dimens.y -= delta.y; } else if (selectedDirection == Direction.LEFT) { position.x -= delta.x; dimens.x += delta.x; } else { // Direction.RIGHT dimens.x -= delta.x; } updateExtents(); return true; } @Override public boolean handleLongPress() { return false; } @Override public JSONObject toJSON() throws JSONException { JSONObject json = new JSONObject(); json.put(TYPE_KEY, getType()); json.put(X_KEY, position.x); json.put(Y_KEY, position.y); json.put(DIMENS_X_KEY, dimens.x); json.put(DIMENS_Y_KEY, dimens.y); return json; } private void updateExtents() { upMidpoint.set(position).add(dimens.x / 2, 0); downMidpoint.set(position).add(dimens.x / 2, dimens.y); leftMidpoint.set(position).add(0, dimens.y / 2); rightMidpoint.set(position).add(dimens.x, dimens.y / 2); } public static ColoredRectangleActor fromJSON(JSONObject json) throws JSONException { String type = json.getString(Actor.TYPE_KEY); Vector2D position = Vector2D.get( (float) json.optDouble(X_KEY, 0), (float) json.optDouble(Y_KEY, 0)); Vector2D dimens = Vector2D.get( (float) json.optDouble(DIMENS_X_KEY, 0), (float) json.optDouble(DIMENS_Y_KEY, 0)); return new ColoredRectangleActor(position, dimens, type); } }