blob: d991814f3a7f0dccd33389c4958e13793c8bbb63 [file] [log] [blame]
/*
* Copyright (C) 2008 The Android Open Source Project
*
* 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.android.deskclock;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import com.android.deskclock.timer.TimerView;
public class TimerSetupView extends LinearLayout implements Button.OnClickListener,
Button.OnLongClickListener{
protected int mInputSize = 5;
protected final Button mNumbers [] = new Button [10];
protected int mInput [] = new int [mInputSize];
protected int mInputPointer = -1;
protected Button mLeft, mRight;
protected ImageButton mStart;
protected ImageButton mDelete;
protected TimerView mEnteredTime;
protected View mDivider;
protected final Context mContext;
private final AnimatorListenerAdapter mHideFabAnimatorListener = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (mStart != null) {
mStart.setScaleX(1.0f);
mStart.setScaleY(1.0f);
mStart.setVisibility(View.INVISIBLE);
}
}
};
private final AnimatorListenerAdapter mShowFabAnimatorListener = new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
if (mStart != null) {
mStart.setVisibility(View.VISIBLE);
}
}
};
public TimerSetupView(Context context) {
this(context, null);
}
public TimerSetupView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
LayoutInflater layoutInflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
layoutInflater.inflate(R.layout.time_setup_view, this);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
View v1 = findViewById(R.id.first);
View v2 = findViewById(R.id.second);
View v3 = findViewById(R.id.third);
View v4 = findViewById(R.id.fourth);
mEnteredTime = (TimerView)findViewById(R.id.timer_time_text);
mDelete = (ImageButton)findViewById(R.id.delete);
mDelete.setOnClickListener(this);
mDelete.setOnLongClickListener(this);
mDivider = findViewById(R.id.divider);
mNumbers[1] = (Button)v1.findViewById(R.id.key_left);
mNumbers[2] = (Button)v1.findViewById(R.id.key_middle);
mNumbers[3] = (Button)v1.findViewById(R.id.key_right);
mNumbers[4] = (Button)v2.findViewById(R.id.key_left);
mNumbers[5] = (Button)v2.findViewById(R.id.key_middle);
mNumbers[6] = (Button)v2.findViewById(R.id.key_right);
mNumbers[7] = (Button)v3.findViewById(R.id.key_left);
mNumbers[8] = (Button)v3.findViewById(R.id.key_middle);
mNumbers[9] = (Button)v3.findViewById(R.id.key_right);
mLeft = (Button)v4.findViewById(R.id.key_left);
mNumbers[0] = (Button)v4.findViewById(R.id.key_middle);
mRight = (Button)v4.findViewById(R.id.key_right);
mLeft.setVisibility(INVISIBLE);
mRight.setVisibility(INVISIBLE);
for (int i = 0; i < 10; i++) {
mNumbers[i].setOnClickListener(this);
mNumbers[i].setText(String.format("%d", i));
mNumbers[i].setTextColor(Color.WHITE);
mNumbers[i].setTag(R.id.numbers_key, new Integer(i));
}
updateTime();
}
public void registerStartButton(ImageButton start) {
mStart = start;
initializeStartButtonVisibility();
}
private void initializeStartButtonVisibility() {
if (mStart != null) {
mStart.setVisibility(isInputHasValue() ? View.VISIBLE : View.INVISIBLE);
}
}
private void updateStartButton() {
setFabButtonVisibility(isInputHasValue() /* show or hide */);
}
public void updateDeleteButtonAndDivider() {
final boolean enabled = isInputHasValue();
if (mDelete != null) {
mDelete.setEnabled(enabled);
mDivider.setBackgroundResource(enabled ? R.color.hot_pink : R.color.dialog_gray);
}
}
private boolean isInputHasValue() {
return mInputPointer != -1;
}
private void setFabButtonVisibility(boolean show) {
final int finalVisibility = show ? View.VISIBLE : View.INVISIBLE;
if (mStart == null || mStart.getVisibility() == finalVisibility) {
// Fab is not initialized yet or already shown/hidden
return;
}
final Animator scaleAnimator = AnimatorUtils.getScaleAnimator(
mStart, show ? 0.0f : 1.0f, show ? 1.0f : 0.0f);
scaleAnimator.setDuration(AnimatorUtils.ANIM_DURATION_SHORT);
scaleAnimator.addListener(show ? mShowFabAnimatorListener : mHideFabAnimatorListener);
scaleAnimator.start();
}
@Override
public void onClick(View v) {
doOnClick(v);
updateStartButton();
updateDeleteButtonAndDivider();
}
protected void doOnClick(View v) {
Integer val = (Integer) v.getTag(R.id.numbers_key);
// A number was pressed
if (val != null) {
// pressing "0" as the first digit does nothing
if (mInputPointer == -1 && val == 0) {
return;
}
if (mInputPointer < mInputSize - 1) {
for (int i = mInputPointer; i >= 0; i--) {
mInput[i+1] = mInput[i];
}
mInputPointer++;
mInput [0] = val;
// Update so talkback will read the number being deleted
mDelete.setContentDescription(
getResources().getString(R.string.timer_descriptive_delete,
Integer.toString(val)));
updateTime();
}
return;
}
// other keys
if (v == mDelete) {
if (mInputPointer >= 0) {
for (int i = 0; i < mInputPointer; i++) {
mInput[i] = mInput[i + 1];
}
mInput[mInputPointer] = 0;
mInputPointer--;
updateTime();
}
// update so talkback will read either the next number or its original description
// if there are no more numbers.
mDelete.setContentDescription(getResources().getString(
R.string.timer_descriptive_delete,
mInputPointer < 0 ? "" : Integer.toString(mInput[mInputPointer])));
}
}
@Override
public boolean onLongClick(View v) {
if (v == mDelete) {
reset();
updateStartButton();
updateDeleteButtonAndDivider();
return true;
}
return false;
}
protected void updateTime() {
mEnteredTime.setTime(mInput[4], mInput[3], mInput[2],
mInput[1] * 10 + mInput[0]);
}
public void reset() {
for (int i = 0; i < mInputSize; i ++) {
mInput[i] = 0;
}
mInputPointer = -1;
updateTime();
}
public int getTime() {
return mInput[4] * 3600 + mInput[3] * 600 + mInput[2] * 60 + mInput[1] * 10 + mInput[0];
}
public void saveEntryState(Bundle outState, String key) {
outState.putIntArray(key, mInput);
}
public void restoreEntryState(Bundle inState, String key) {
int[] input = inState.getIntArray(key);
if (input != null && mInputSize == input.length) {
for (int i = 0; i < mInputSize; i++) {
mInput[i] = input[i];
if (mInput[i] != 0) {
mInputPointer = i;
}
}
updateTime();
}
initializeStartButtonVisibility();
}
}