Home | History | Annotate | Download | only in deskclock
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.deskclock;
     18 
     19 import android.animation.Animator;
     20 import android.animation.AnimatorListenerAdapter;
     21 import android.content.Context;
     22 import android.graphics.Color;
     23 import android.os.Bundle;
     24 import android.util.AttributeSet;
     25 import android.view.LayoutInflater;
     26 import android.view.View;
     27 import android.widget.Button;
     28 import android.widget.ImageButton;
     29 import android.widget.LinearLayout;
     30 
     31 import com.android.deskclock.timer.TimerView;
     32 
     33 
     34 public class TimerSetupView extends LinearLayout implements Button.OnClickListener,
     35         Button.OnLongClickListener{
     36 
     37     protected int mInputSize = 5;
     38 
     39     protected final Button mNumbers [] = new Button [10];
     40     protected int mInput [] = new int [mInputSize];
     41     protected int mInputPointer = -1;
     42     protected Button mLeft, mRight;
     43     protected ImageButton mStart;
     44     protected ImageButton mDelete;
     45     protected TimerView mEnteredTime;
     46     protected View mDivider;
     47     protected final Context mContext;
     48 
     49     private final AnimatorListenerAdapter mHideFabAnimatorListener = new AnimatorListenerAdapter() {
     50         @Override
     51         public void onAnimationEnd(Animator animation) {
     52             if (mStart != null) {
     53                 mStart.setScaleX(1.0f);
     54                 mStart.setScaleY(1.0f);
     55                 mStart.setVisibility(View.INVISIBLE);
     56             }
     57         }
     58     };
     59 
     60     private final AnimatorListenerAdapter mShowFabAnimatorListener = new AnimatorListenerAdapter() {
     61         @Override
     62         public void onAnimationStart(Animator animation) {
     63             if (mStart != null) {
     64                 mStart.setVisibility(View.VISIBLE);
     65             }
     66         }
     67     };
     68 
     69     public TimerSetupView(Context context) {
     70         this(context, null);
     71     }
     72 
     73     public TimerSetupView(Context context, AttributeSet attrs) {
     74         super(context, attrs);
     75         mContext = context;
     76         LayoutInflater layoutInflater =
     77                 (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
     78         layoutInflater.inflate(R.layout.time_setup_view, this);
     79     }
     80 
     81     @Override
     82     protected void onFinishInflate() {
     83         super.onFinishInflate();
     84 
     85         View v1 = findViewById(R.id.first);
     86         View v2 = findViewById(R.id.second);
     87         View v3 = findViewById(R.id.third);
     88         View v4 = findViewById(R.id.fourth);
     89 
     90         mEnteredTime = (TimerView)findViewById(R.id.timer_time_text);
     91         mDelete = (ImageButton)findViewById(R.id.delete);
     92         mDelete.setOnClickListener(this);
     93         mDelete.setOnLongClickListener(this);
     94         mDivider = findViewById(R.id.divider);
     95 
     96         mNumbers[1] = (Button)v1.findViewById(R.id.key_left);
     97         mNumbers[2] = (Button)v1.findViewById(R.id.key_middle);
     98         mNumbers[3] = (Button)v1.findViewById(R.id.key_right);
     99 
    100         mNumbers[4] = (Button)v2.findViewById(R.id.key_left);
    101         mNumbers[5] = (Button)v2.findViewById(R.id.key_middle);
    102         mNumbers[6] = (Button)v2.findViewById(R.id.key_right);
    103 
    104         mNumbers[7] = (Button)v3.findViewById(R.id.key_left);
    105         mNumbers[8] = (Button)v3.findViewById(R.id.key_middle);
    106         mNumbers[9] = (Button)v3.findViewById(R.id.key_right);
    107 
    108         mLeft = (Button)v4.findViewById(R.id.key_left);
    109         mNumbers[0] = (Button)v4.findViewById(R.id.key_middle);
    110         mRight = (Button)v4.findViewById(R.id.key_right);
    111 
    112         mLeft.setVisibility(INVISIBLE);
    113         mRight.setVisibility(INVISIBLE);
    114 
    115         for (int i = 0; i < 10; i++) {
    116             mNumbers[i].setOnClickListener(this);
    117             mNumbers[i].setText(String.format("%d", i));
    118             mNumbers[i].setTextColor(Color.WHITE);
    119             mNumbers[i].setTag(R.id.numbers_key, new Integer(i));
    120         }
    121         updateTime();
    122     }
    123 
    124     public void registerStartButton(ImageButton start) {
    125         mStart = start;
    126         initializeStartButtonVisibility();
    127     }
    128 
    129     private void initializeStartButtonVisibility() {
    130         if (mStart != null) {
    131             mStart.setVisibility(isInputHasValue() ? View.VISIBLE : View.INVISIBLE);
    132         }
    133     }
    134 
    135     private void updateStartButton() {
    136         setFabButtonVisibility(isInputHasValue() /* show or hide */);
    137     }
    138 
    139     public void updateDeleteButtonAndDivider() {
    140         final boolean enabled = isInputHasValue();
    141         if (mDelete != null) {
    142             mDelete.setEnabled(enabled);
    143             mDivider.setBackgroundResource(enabled ? R.color.hot_pink : R.color.dialog_gray);
    144         }
    145     }
    146 
    147     private boolean isInputHasValue() {
    148         return mInputPointer != -1;
    149     }
    150 
    151     private void setFabButtonVisibility(boolean show) {
    152         final int finalVisibility = show ? View.VISIBLE : View.INVISIBLE;
    153         if (mStart == null || mStart.getVisibility() == finalVisibility) {
    154             // Fab is not initialized yet or already shown/hidden
    155             return;
    156         }
    157 
    158         final Animator scaleAnimator = AnimatorUtils.getScaleAnimator(
    159                 mStart, show ? 0.0f : 1.0f, show ? 1.0f : 0.0f);
    160         scaleAnimator.setDuration(AnimatorUtils.ANIM_DURATION_SHORT);
    161         scaleAnimator.addListener(show ? mShowFabAnimatorListener : mHideFabAnimatorListener);
    162         scaleAnimator.start();
    163     }
    164 
    165     @Override
    166     public void onClick(View v) {
    167         doOnClick(v);
    168         updateStartButton();
    169         updateDeleteButtonAndDivider();
    170     }
    171 
    172     protected void doOnClick(View v) {
    173 
    174         Integer val = (Integer) v.getTag(R.id.numbers_key);
    175         // A number was pressed
    176         if (val != null) {
    177             // pressing "0" as the first digit does nothing
    178             if (mInputPointer == -1 && val == 0) {
    179                 return;
    180             }
    181             if (mInputPointer < mInputSize - 1) {
    182                 for (int i = mInputPointer; i >= 0; i--) {
    183                     mInput[i+1] = mInput[i];
    184                 }
    185                 mInputPointer++;
    186                 mInput [0] = val;
    187                 updateTime();
    188             }
    189             return;
    190         }
    191 
    192         // other keys
    193         if (v == mDelete) {
    194             if (mInputPointer >= 0) {
    195                 for (int i = 0; i < mInputPointer; i++) {
    196                     mInput[i] = mInput[i + 1];
    197                 }
    198                 mInput[mInputPointer] = 0;
    199                 mInputPointer--;
    200                 updateTime();
    201             }
    202         }
    203     }
    204 
    205     @Override
    206     public boolean onLongClick(View v) {
    207         if (v == mDelete) {
    208             reset();
    209             updateStartButton();
    210             updateDeleteButtonAndDivider();
    211             return true;
    212         }
    213         return false;
    214     }
    215 
    216     protected void updateTime() {
    217         mEnteredTime.setTime(mInput[4], mInput[3], mInput[2],
    218                 mInput[1] * 10 + mInput[0]);
    219     }
    220 
    221     public void reset() {
    222         for (int i = 0; i < mInputSize; i ++) {
    223             mInput[i] = 0;
    224         }
    225         mInputPointer = -1;
    226         updateTime();
    227     }
    228 
    229     public int getTime() {
    230         return mInput[4] * 3600 + mInput[3] * 600 + mInput[2] * 60 + mInput[1] * 10 + mInput[0];
    231     }
    232 
    233     public void saveEntryState(Bundle outState, String key) {
    234         outState.putIntArray(key, mInput);
    235     }
    236 
    237     public void restoreEntryState(Bundle inState, String key) {
    238         int[] input = inState.getIntArray(key);
    239         if (input != null && mInputSize == input.length) {
    240             for (int i = 0; i < mInputSize; i++) {
    241                 mInput[i] = input[i];
    242                 if (mInput[i] != 0) {
    243                     mInputPointer = i;
    244                 }
    245             }
    246             updateTime();
    247         }
    248         initializeStartButtonVisibility();
    249     }
    250 }
    251