1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 * except in compliance with the License. You may obtain a copy of the License at
6 *
7 *      http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the
10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11 * KIND, either express or implied. See the License for the specific language governing
12 * permissions and limitations under the License.
13 */
14
15package com.android.systemui.tuner;
16
17import android.annotation.Nullable;
18import android.app.AlertDialog;
19import android.app.Dialog;
20import android.app.DialogFragment;
21import android.content.Context;
22import android.content.DialogInterface;
23import android.content.DialogInterface.OnClickListener;
24import android.os.Bundle;
25import android.support.v14.preference.ListPreferenceDialogFragment;
26import android.support.v7.preference.ListPreference;
27import android.util.AttributeSet;
28import android.view.LayoutInflater;
29import android.view.View;
30import android.view.ViewGroup;
31
32public class CustomListPreference extends ListPreference {
33
34    public CustomListPreference(Context context, AttributeSet attrs) {
35        super(context, attrs);
36    }
37
38    public CustomListPreference(Context context, AttributeSet attrs, int defStyleAttr,
39                                int defStyleRes) {
40        super(context, attrs, defStyleAttr, defStyleRes);
41    }
42
43    protected void onPrepareDialogBuilder(AlertDialog.Builder builder,
44            OnClickListener listener) {
45    }
46
47    protected void onDialogClosed(boolean positiveResult) {
48    }
49
50    protected Dialog onDialogCreated(DialogFragment fragment, Dialog dialog) {
51        return dialog;
52    }
53
54    protected boolean isAutoClosePreference() {
55        return true;
56    }
57
58    /**
59     * Called when a user is about to choose the given value, to determine if we
60     * should show a confirmation dialog.
61     *
62     * @param value the value the user is about to choose
63     * @return the message to show in a confirmation dialog, or {@code null} to
64     *         not request confirmation
65     */
66    protected CharSequence getConfirmationMessage(String value) {
67        return null;
68    }
69
70    protected void onDialogStateRestored(DialogFragment fragment, Dialog dialog,
71            Bundle savedInstanceState) {
72    }
73
74    public static class CustomListPreferenceDialogFragment extends ListPreferenceDialogFragment {
75
76        private static final String KEY_CLICKED_ENTRY_INDEX
77                = "settings.CustomListPrefDialog.KEY_CLICKED_ENTRY_INDEX";
78
79        private int mClickedDialogEntryIndex;
80
81        public static ListPreferenceDialogFragment newInstance(String key) {
82            final ListPreferenceDialogFragment fragment = new CustomListPreferenceDialogFragment();
83            final Bundle b = new Bundle(1);
84            b.putString(ARG_KEY, key);
85            fragment.setArguments(b);
86            return fragment;
87        }
88
89        public CustomListPreference getCustomizablePreference() {
90            return (CustomListPreference) getPreference();
91        }
92
93        @Override
94        protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
95            super.onPrepareDialogBuilder(builder);
96            mClickedDialogEntryIndex = getCustomizablePreference()
97                    .findIndexOfValue(getCustomizablePreference().getValue());
98            getCustomizablePreference().onPrepareDialogBuilder(builder, getOnItemClickListener());
99            if (!getCustomizablePreference().isAutoClosePreference()) {
100                builder.setPositiveButton(com.android.internal.R.string.ok, new OnClickListener() {
101                    @Override
102                    public void onClick(DialogInterface dialog, int which) {
103                        onItemConfirmed();
104                    }
105                });
106            }
107        }
108
109        @Override
110        public Dialog onCreateDialog(Bundle savedInstanceState) {
111            Dialog dialog = super.onCreateDialog(savedInstanceState);
112            if (savedInstanceState != null) {
113                mClickedDialogEntryIndex = savedInstanceState.getInt(KEY_CLICKED_ENTRY_INDEX,
114                        mClickedDialogEntryIndex);
115            }
116            return getCustomizablePreference().onDialogCreated(this, dialog);
117        }
118
119        @Override
120        public void onSaveInstanceState(Bundle outState) {
121            super.onSaveInstanceState(outState);
122            outState.putInt(KEY_CLICKED_ENTRY_INDEX, mClickedDialogEntryIndex);
123        }
124
125        @Override
126        public void onActivityCreated(Bundle savedInstanceState) {
127            super.onActivityCreated(savedInstanceState);
128            getCustomizablePreference().onDialogStateRestored(this, getDialog(), savedInstanceState);
129        }
130
131        protected OnClickListener getOnItemClickListener() {
132            return new OnClickListener() {
133                @Override
134                public void onClick(DialogInterface dialog, int which) {
135                    setClickedDialogEntryIndex(which);
136                    if (getCustomizablePreference().isAutoClosePreference()) {
137                        onItemConfirmed();
138                    }
139                }
140            };
141        }
142
143        protected void setClickedDialogEntryIndex(int which) {
144            mClickedDialogEntryIndex = which;
145        }
146
147        private String getValue() {
148            final ListPreference preference = getCustomizablePreference();
149            if (mClickedDialogEntryIndex >= 0 && preference.getEntryValues() != null) {
150                return preference.getEntryValues()[mClickedDialogEntryIndex].toString();
151            } else {
152                return null;
153            }
154        }
155
156        protected void onItemConfirmed() {
157            onClick(getDialog(), DialogInterface.BUTTON_POSITIVE);
158            getDialog().dismiss();
159        }
160
161        @Override
162        public void onDialogClosed(boolean positiveResult) {
163            getCustomizablePreference().onDialogClosed(positiveResult);
164            final ListPreference preference = getCustomizablePreference();
165            final String value = getValue();
166            if (positiveResult && value != null) {
167                if (preference.callChangeListener(value)) {
168                    preference.setValue(value);
169                }
170            }
171        }
172    }
173}
174