blob: c0d1cac526758dcb4af4b2587f8a6f391615400d [file] [log] [blame]
/*
* Copyright (C) 2014 Google, Inc.
*
* 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.projectara.araepm;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.view.animation.TranslateAnimation;
import android.view.View;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.RelativeLayout;
import android.widget.Switch;
import android.widget.Toast;
public class MainActivity extends Activity
implements EpmController.EpmChangeCallback {
private static final String TAG = "AraEPM";
private static final int LOCK_TRANSLATE_DISTANCE = 40;
//
// The following group of fields are locked by `this'.
//
// If true, an EPM change is ongoing.
private boolean epmChangeOngoing;
// If false, button clicks will be ignored.
private boolean buttonPressesEnabled;
private EpmController epmController;
private static String EPM_ATTACHED;
private static String EPM_DETACHED;
private static String EPM_ATTACHING;
private static String EPM_DETACHING;
private static String EPM_STATUS_OK;
private static String EPM_STATUS_ERROR;
private static String EPM_STATUS_TIMEOUT;
private Module modules[];
private class Module implements View.OnClickListener, AnimatorListener {
private boolean locked;
private boolean isLeft;
private ImageView view;
private int port;
public Module(ImageView view, boolean isLeft, int port) {
this.locked = true;
this.view = view;
this.isLeft = isLeft;
this.port = port;
view.setScaleType(ScaleType.CENTER);
view.setImageResource(R.drawable.lock_sky);
view.animate().setListener(this);
view.setOnClickListener(this);
}
public String toString() {
return "ModuleOnClickListener(isLeft=" + isLeft +
", port=" + port+ ",locked=" + locked + ")";
}
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
Log.d(TAG, "onAnimationEnd");
if (locked) {
view.setScaleType(ScaleType.CENTER);
view.setImageResource(R.drawable.lock_sky);
} else {
view.setImageResource(R.drawable.lock_open_gray);
}
// synchronized (this) {
// enableButtonPressesLocked();
// }
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
// The layout, ignoring the buttons that are occupied by the
// switch (marked XX), looks like this, with port numbers
// underneath:
//
// +-----------------------+
// | | R1 |
// | L1 | 4 |
// | 3 +---------------+
// | | |
// | | |
// +-------+ R2 +
// | | 2 |
// | L2 | |
// | 1 +---------------+
// | | |
// | | |
// +-------+ R3 +
// | | 0 |
// | XX | |
// | +---------------+
// | | XX |
// | | |
// +-----------------------+
/**
* Handles EPM changes and mutual exclusion between buttons.
*
* Example arguments for a button listener to attach the top
* left EPM, when endo is viewed from rear:
*
* - isLeft=true
* - port=0
*
* @param isLeft Is the button on the left side of the endo,
* when viewed from the rear?
* @param port port number, see above
*/
@Override
public void onClick(View v) {
Log.d(TAG, "onClick() handler called on: " +
this.toString());
synchronized (MainActivity.this) {
if (!buttonPressesEnabled) {
Log.d(TAG, "Ignoring click while EPM change is ongoing");
return;
} else {
epmChangeOngoing = true;
disableButtonPressesLocked();
}
}
Log.i(TAG,
(locked ? "Detaching " : "Attaching ") +
" EPM on port " );
int distance = this.isLeft ? -LOCK_TRANSLATE_DISTANCE : LOCK_TRANSLATE_DISTANCE;
if (locked) {
v.animate().xBy(distance);
epmController.detachEpm(port);
} else {
v.animate().xBy(-distance);
epmController.attachEpm(port);
}
this.locked = !locked;
Log.d(TAG, "onClick() handler finished");
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initializeImageviewAnimation();
}
private void enableButtonPressesLocked() {
Log.d(TAG, "enabling button presses");
if (epmChangeOngoing) {
Log.wtf(TAG, "epm change is still ongoing!");
}
buttonPressesEnabled = true;
}
private void disableButtonPressesLocked() {
Log.d(TAG, "disabling button presses");
buttonPressesEnabled = false;
}
@Override
protected void onStart() {
super.onStart();
epmController = new EpmController(this, this);
epmController.start();
EPM_ATTACHED = getString(R.string.epm_attached);
EPM_DETACHED = getString(R.string.epm_detached);
EPM_ATTACHING = getString(R.string.epm_attaching);
EPM_DETACHING = getString(R.string.epm_detaching);
EPM_STATUS_OK = getString(R.string.epm_status_ok);
EPM_STATUS_ERROR = getString(R.string.epm_status_error);
EPM_STATUS_TIMEOUT = getString(R.string.epm_status_timeout);
}
@Override
protected void onStop() {
super.onStop();
epmController.stop();
epmController = null;
}
public void initializeImageviewAnimation() {
modules = new Module[] {
new Module((ImageView)findViewById(R.id.leftside_first_left_dwar_detach), true, 3),
new Module((ImageView)findViewById(R.id.leftside_2nd_left_dwar_detach), true, 1),
new Module((ImageView)findViewById(R.id.rightside_1st_left_dwar_detach), false, 4),
new Module((ImageView)findViewById(R.id.rightside_2nd_left_dwar_detach), false, 2),
new Module((ImageView)findViewById(R.id.rightside_3rd_left_dwar_detach), false, 0),
};
synchronized (this) {
epmChangeOngoing = false;
enableButtonPressesLocked();
}
}
public void onEpmChangeFinished(EpmController.EpmState state,
EpmController.EpmChangeStatus status,
int port) {
Log.d(TAG, "onEpmChangeFinished: state=" + state + ", status=" + status +
", port=" + port);
String s;
switch (state) {
case EPM_ATTACH:
s = EPM_ATTACHED;
break;
case EPM_DETACH:
s = EPM_DETACHED;
break;
default:
Log.wtf(TAG, "can't happen");
s = null;
return;
}
String statusFormat;
switch (status) {
case EPM_OK:
statusFormat = EPM_STATUS_OK;
break;
case EPM_ERROR:
statusFormat = EPM_STATUS_ERROR;
break;
case EPM_TIMEOUT:
statusFormat = EPM_STATUS_TIMEOUT;
break;
default:
Log.wtf(TAG, "can't happen");
statusFormat = null;
return;
}
if (s != null && statusFormat != null) {
int duration = Toast.LENGTH_SHORT;
String text = String.format(statusFormat, s, port);
Toast toast = Toast.makeText(getApplicationContext(), text,
duration);
toast.show();
}
synchronized (this) {
epmChangeOngoing = false;
enableButtonPressesLocked();
}
}
}