| /* |
| * Copyright (C) 2017 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.systemui.tuner; |
| |
| import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.KEY; |
| import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.KEY_CODE_END; |
| import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.KEY_CODE_START; |
| import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.KEY_IMAGE_DELIM; |
| import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.MENU_IME_ROTATE; |
| import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.NAVSPACE; |
| import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.NAV_BAR_LEFT; |
| import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.NAV_BAR_RIGHT; |
| import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.NAV_BAR_VIEWS; |
| import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.extractButton; |
| import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.extractImage; |
| import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.extractKeycode; |
| |
| import android.annotation.Nullable; |
| import android.app.AlertDialog; |
| import android.graphics.Color; |
| import android.graphics.drawable.Drawable; |
| import android.graphics.drawable.Icon; |
| import android.os.Bundle; |
| import android.os.Handler; |
| import androidx.preference.ListPreference; |
| import androidx.preference.Preference; |
| import androidx.preference.Preference.OnPreferenceChangeListener; |
| import android.text.SpannableStringBuilder; |
| import android.text.style.ImageSpan; |
| import android.util.Log; |
| import android.util.TypedValue; |
| import android.view.KeyEvent; |
| import android.widget.EditText; |
| |
| import com.android.systemui.Dependency; |
| import com.android.systemui.R; |
| import com.android.systemui.tuner.TunerService.Tunable; |
| |
| import java.util.ArrayList; |
| |
| public class NavBarTuner extends TunerPreferenceFragment { |
| |
| private static final String LAYOUT = "layout"; |
| private static final String LEFT = "left"; |
| private static final String RIGHT = "right"; |
| |
| private static final String TYPE = "type"; |
| private static final String KEYCODE = "keycode"; |
| private static final String ICON = "icon"; |
| |
| private static final int[][] ICONS = new int[][]{ |
| {R.drawable.ic_qs_circle, R.string.tuner_circle}, |
| {R.drawable.ic_add, R.string.tuner_plus}, |
| {R.drawable.ic_remove, R.string.tuner_minus}, |
| {R.drawable.ic_left, R.string.tuner_left}, |
| {R.drawable.ic_right, R.string.tuner_right}, |
| {R.drawable.ic_menu, R.string.tuner_menu}, |
| }; |
| |
| private final ArrayList<Tunable> mTunables = new ArrayList<>(); |
| private Handler mHandler; |
| |
| @Override |
| public void onCreate(@Nullable Bundle savedInstanceState) { |
| mHandler = new Handler(); |
| super.onCreate(savedInstanceState); |
| } |
| |
| @Override |
| public void onActivityCreated(@Nullable Bundle savedInstanceState) { |
| super.onActivityCreated(savedInstanceState); |
| getActivity().getActionBar().setDisplayHomeAsUpEnabled(true); |
| } |
| |
| @Override |
| public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { |
| addPreferencesFromResource(R.xml.nav_bar_tuner); |
| bindLayout((ListPreference) findPreference(LAYOUT)); |
| bindButton(NAV_BAR_LEFT, NAVSPACE, LEFT); |
| bindButton(NAV_BAR_RIGHT, MENU_IME_ROTATE, RIGHT); |
| } |
| |
| @Override |
| public void onDestroy() { |
| super.onDestroy(); |
| mTunables.forEach(t -> Dependency.get(TunerService.class).removeTunable(t)); |
| } |
| |
| private void addTunable(Tunable tunable, String... keys) { |
| mTunables.add(tunable); |
| Dependency.get(TunerService.class).addTunable(tunable, keys); |
| } |
| |
| private void bindLayout(ListPreference preference) { |
| addTunable((key, newValue) -> mHandler.post(() -> { |
| String val = newValue; |
| if (val == null) { |
| val = "default"; |
| } |
| preference.setValue(val); |
| }), NAV_BAR_VIEWS); |
| preference.setOnPreferenceChangeListener((preference1, newValue) -> { |
| String val = (String) newValue; |
| if ("default".equals(val)) val = null; |
| Dependency.get(TunerService.class).setValue(NAV_BAR_VIEWS, val); |
| return true; |
| }); |
| } |
| |
| private void bindButton(String setting, String def, String k) { |
| ListPreference type = (ListPreference) findPreference(TYPE + "_" + k); |
| Preference keycode = findPreference(KEYCODE + "_" + k); |
| ListPreference icon = (ListPreference) findPreference(ICON + "_" + k); |
| setupIcons(icon); |
| addTunable((key, newValue) -> mHandler.post(() -> { |
| String val = newValue; |
| if (val == null) { |
| val = def; |
| } |
| String button = extractButton(val); |
| if (button.startsWith(KEY)) { |
| type.setValue(KEY); |
| String uri = extractImage(button); |
| int code = extractKeycode(button); |
| icon.setValue(uri); |
| updateSummary(icon); |
| keycode.setSummary(code + ""); |
| keycode.setVisible(true); |
| icon.setVisible(true); |
| } else { |
| type.setValue(button); |
| keycode.setVisible(false); |
| icon.setVisible(false); |
| } |
| }), setting); |
| OnPreferenceChangeListener listener = (preference, newValue) -> { |
| mHandler.post(() -> { |
| setValue(setting, type, keycode, icon); |
| updateSummary(icon); |
| }); |
| return true; |
| }; |
| type.setOnPreferenceChangeListener(listener); |
| icon.setOnPreferenceChangeListener(listener); |
| keycode.setOnPreferenceClickListener(preference -> { |
| EditText editText = new EditText(getContext()); |
| new AlertDialog.Builder(getContext()) |
| .setTitle(preference.getTitle()) |
| .setView(editText) |
| .setNegativeButton(android.R.string.cancel, null) |
| .setPositiveButton(android.R.string.ok, (dialog, which) -> { |
| int code = KeyEvent.KEYCODE_ENTER; |
| try { |
| code = Integer.parseInt(editText.getText().toString()); |
| } catch (Exception e) { |
| } |
| keycode.setSummary(code + ""); |
| setValue(setting, type, keycode, icon); |
| }).show(); |
| return true; |
| }); |
| } |
| |
| private void updateSummary(ListPreference icon) { |
| try { |
| int size = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 14, |
| getContext().getResources().getDisplayMetrics()); |
| String pkg = icon.getValue().split("/")[0]; |
| int id = Integer.parseInt(icon.getValue().split("/")[1]); |
| SpannableStringBuilder builder = new SpannableStringBuilder(); |
| Drawable d = Icon.createWithResource(pkg, id) |
| .loadDrawable(getContext()); |
| d.setTint(Color.BLACK); |
| d.setBounds(0, 0, size, size); |
| ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE); |
| builder.append(" ", span, 0); |
| builder.append(" "); |
| for (int i = 0; i < ICONS.length; i++) { |
| if (ICONS[i][0] == id) { |
| builder.append(getString(ICONS[i][1])); |
| } |
| } |
| icon.setSummary(builder); |
| } catch (Exception e) { |
| Log.d("NavButton", "Problem with summary", e); |
| icon.setSummary(null); |
| } |
| } |
| |
| private void setValue(String setting, ListPreference type, Preference keycode, |
| ListPreference icon) { |
| String button = type.getValue(); |
| if (KEY.equals(button)) { |
| String uri = icon.getValue(); |
| int code = KeyEvent.KEYCODE_ENTER; |
| try { |
| code = Integer.parseInt(keycode.getSummary().toString()); |
| } catch (Exception e) { |
| } |
| button = button + KEY_CODE_START + code + KEY_IMAGE_DELIM + uri + KEY_CODE_END; |
| } |
| Dependency.get(TunerService.class).setValue(setting, button); |
| } |
| |
| private void setupIcons(ListPreference icon) { |
| CharSequence[] labels = new CharSequence[ICONS.length]; |
| CharSequence[] values = new CharSequence[ICONS.length]; |
| int size = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 14, |
| getContext().getResources().getDisplayMetrics()); |
| for (int i = 0; i < ICONS.length; i++) { |
| SpannableStringBuilder builder = new SpannableStringBuilder(); |
| Drawable d = Icon.createWithResource(getContext().getPackageName(), ICONS[i][0]) |
| .loadDrawable(getContext()); |
| d.setTint(Color.BLACK); |
| d.setBounds(0, 0, size, size); |
| ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE); |
| builder.append(" ", span, 0); |
| builder.append(" "); |
| builder.append(getString(ICONS[i][1])); |
| labels[i] = builder; |
| values[i] = getContext().getPackageName() + "/" + ICONS[i][0]; |
| } |
| icon.setEntries(labels); |
| icon.setEntryValues(values); |
| } |
| } |