Home | History | Annotate | Download | only in deskclock
      1 /*
      2  * Copyright (C) 2012 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.app.Dialog;
     20 import android.app.DialogFragment;
     21 import android.content.Context;
     22 import android.content.DialogInterface;
     23 import android.content.res.ColorStateList;
     24 import android.os.Bundle;
     25 import android.support.annotation.NonNull;
     26 import android.support.v7.app.AlertDialog;
     27 import android.support.v7.widget.AppCompatEditText;
     28 import android.text.Editable;
     29 import android.text.InputType;
     30 import android.text.TextUtils;
     31 import android.text.TextWatcher;
     32 import android.view.KeyEvent;
     33 import android.view.inputmethod.EditorInfo;
     34 import android.widget.TextView;
     35 
     36 import com.android.deskclock.data.DataModel;
     37 import com.android.deskclock.data.Timer;
     38 import com.android.deskclock.provider.Alarm;
     39 
     40 import static android.graphics.Color.RED;
     41 import static android.graphics.Color.WHITE;
     42 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE;
     43 
     44 /**
     45  * DialogFragment to edit label.
     46  */
     47 public class LabelDialogFragment extends DialogFragment {
     48 
     49     private static final String KEY_LABEL = "label";
     50     private static final String KEY_ALARM = "alarm";
     51     private static final String KEY_TIMER_ID = "timer_id";
     52     private static final String KEY_TAG = "tag";
     53 
     54     private AppCompatEditText mLabelBox;
     55     private Alarm mAlarm;
     56     private int mTimerId;
     57     private String mTag;
     58 
     59     public static LabelDialogFragment newInstance(Alarm alarm, String label, String tag) {
     60         final Bundle args = new Bundle();
     61         args.putString(KEY_LABEL, label);
     62         args.putParcelable(KEY_ALARM, alarm);
     63         args.putString(KEY_TAG, tag);
     64 
     65         final LabelDialogFragment frag = new LabelDialogFragment();
     66         frag.setArguments(args);
     67         return frag;
     68     }
     69 
     70     public static LabelDialogFragment newInstance(Timer timer) {
     71         final Bundle args = new Bundle();
     72         args.putString(KEY_LABEL, timer.getLabel());
     73         args.putInt(KEY_TIMER_ID, timer.getId());
     74 
     75         final LabelDialogFragment frag = new LabelDialogFragment();
     76         frag.setArguments(args);
     77         return frag;
     78     }
     79 
     80     @Override
     81     public void onSaveInstanceState(@NonNull Bundle outState) {
     82         super.onSaveInstanceState(outState);
     83         outState.putString(KEY_LABEL, mLabelBox.getText().toString());
     84     }
     85 
     86     @Override
     87     public Dialog onCreateDialog(Bundle savedInstanceState) {
     88         final Bundle bundle = getArguments();
     89         mAlarm = bundle.getParcelable(KEY_ALARM);
     90         mTimerId = bundle.getInt(KEY_TIMER_ID, -1);
     91         mTag = bundle.getString(KEY_TAG);
     92 
     93         final String label = savedInstanceState != null ?
     94                 savedInstanceState.getString(KEY_LABEL) : bundle.getString(KEY_LABEL);
     95 
     96         final Context context = getActivity();
     97 
     98         mLabelBox = new AppCompatEditText(context);
     99         mLabelBox.setOnEditorActionListener(new ImeDoneListener());
    100         mLabelBox.addTextChangedListener(new TextChangeListener(context));
    101         mLabelBox.setSingleLine();
    102         mLabelBox.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
    103         mLabelBox.setText(label);
    104         mLabelBox.selectAll();
    105 
    106         final int padding = getResources().getDimensionPixelSize(R.dimen.label_edittext_padding);
    107         final AlertDialog alertDialog = new AlertDialog.Builder(context)
    108                 .setView(mLabelBox, padding, 0, padding, 0)
    109                 .setPositiveButton(R.string.time_picker_set, new OkListener())
    110                 .setNegativeButton(R.string.time_picker_cancel, new CancelListener())
    111                 .setMessage(R.string.label)
    112                 .create();
    113 
    114         alertDialog.getWindow().setSoftInputMode(SOFT_INPUT_STATE_VISIBLE);
    115         return alertDialog;
    116     }
    117 
    118     /**
    119      * Sets the new label into the timer or alarm.
    120      */
    121     private void setLabel() {
    122         String label = mLabelBox.getText().toString();
    123         if (label.trim().isEmpty()) {
    124             // Don't allow user to input label with only whitespace.
    125             label = "";
    126         }
    127 
    128         if (mAlarm != null) {
    129             ((AlarmLabelDialogHandler) getActivity()).onDialogLabelSet(mAlarm, label, mTag);
    130         } else if (mTimerId >= 0) {
    131             final Timer timer = DataModel.getDataModel().getTimer(mTimerId);
    132             if (timer != null) {
    133                 DataModel.getDataModel().setTimerLabel(timer, label);
    134             }
    135         }
    136     }
    137 
    138     interface AlarmLabelDialogHandler {
    139         void onDialogLabelSet(Alarm alarm, String label, String tag);
    140     }
    141 
    142     /**
    143      * Alters the UI to indicate when input is valid or invalid.
    144      */
    145     private class TextChangeListener implements TextWatcher {
    146 
    147         private final int colorAccent;
    148         private final int colorControlNormal;
    149 
    150         public TextChangeListener(Context context) {
    151             colorAccent = Utils.obtainStyledColor(context, R.attr.colorAccent, RED);
    152             colorControlNormal = Utils.obtainStyledColor(context, R.attr.colorControlNormal, WHITE);
    153         }
    154 
    155         @Override
    156         public void onTextChanged(CharSequence s, int start, int before, int count) {
    157             final int color = TextUtils.isEmpty(s) ? colorControlNormal : colorAccent;
    158             mLabelBox.setSupportBackgroundTintList(ColorStateList.valueOf(color));
    159         }
    160 
    161         @Override
    162         public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
    163 
    164         @Override
    165         public void afterTextChanged(Editable editable) {}
    166     }
    167 
    168     /**
    169      * Handles completing the label edit from the IME keyboard.
    170      */
    171     private class ImeDoneListener implements TextView.OnEditorActionListener {
    172         @Override
    173         public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
    174             if (actionId == EditorInfo.IME_ACTION_DONE) {
    175                 setLabel();
    176                 dismiss();
    177                 return true;
    178             }
    179             return false;
    180         }
    181     }
    182 
    183     /**
    184      * Handles completing the label edit from the Ok button of the dialog.
    185      */
    186     private class OkListener implements DialogInterface.OnClickListener {
    187         @Override
    188         public void onClick(DialogInterface dialog, int which) {
    189             setLabel();
    190             dismiss();
    191         }
    192     }
    193 
    194     /**
    195      * Handles discarding the label edit from the Cancel button of the dialog.
    196      */
    197     private class CancelListener implements DialogInterface.OnClickListener {
    198         @Override
    199         public void onClick(DialogInterface dialog, int which) {
    200             dismiss();
    201         }
    202     }
    203 }