diff --git a/packages/SystemUI/res/drawable/ic_left.xml b/packages/SystemUI/res/drawable/ic_left.xml
new file mode 100644
index 0000000000000..cea4cfcb13ed3
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_left.xml
@@ -0,0 +1,24 @@
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/ic_menu.xml b/packages/SystemUI/res/drawable/ic_menu.xml
new file mode 100644
index 0000000000000..994bc5e4f12ec
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_menu.xml
@@ -0,0 +1,24 @@
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/ic_remove.xml b/packages/SystemUI/res/drawable/ic_remove.xml
new file mode 100644
index 0000000000000..75b27930842cb
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_remove.xml
@@ -0,0 +1,24 @@
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/ic_right.xml b/packages/SystemUI/res/drawable/ic_right.xml
new file mode 100644
index 0000000000000..35699f733749d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_right.xml
@@ -0,0 +1,24 @@
+
+
+
+
diff --git a/packages/SystemUI/res/values-sw600dp/config.xml b/packages/SystemUI/res/values-sw600dp/config.xml
index fd147cd174042..63b9d75f50546 100644
--- a/packages/SystemUI/res/values-sw600dp/config.xml
+++ b/packages/SystemUI/res/values-sw600dp/config.xml
@@ -34,7 +34,7 @@
true
- space;back,home,recent;menu_ime
+ left;back,home,recent;right
290
diff --git a/packages/SystemUI/res/values-sw900dp/config.xml b/packages/SystemUI/res/values-sw900dp/config.xml
index d8f9ef4e9b2fd..221b0139e713f 100644
--- a/packages/SystemUI/res/values-sw900dp/config.xml
+++ b/packages/SystemUI/res/values-sw900dp/config.xml
@@ -19,6 +19,6 @@
- back,home;space;menu_ime,recent
+ back,home,left;space;right,recent
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index d6ed9d8092ca3..b7647cf7d12f9 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -286,7 +286,7 @@
com.android.systemui.SystemUIFactory
- space,back;home;recent,menu_ime
+ left,back;home;recent,right
false
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index b05cc009a2fae..ef081216e1cb4 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1541,56 +1541,71 @@
Navigation bar
-
- Start
-
- Center
-
- End
-
- Spacer
+
+ Layout
+
+
+ Left
+
+
+ Right
+
+
+ Button type
+
+
+ (default)
+
+
+
+ - Clipboard
+ - Keycode
+ - Menu / Keyboard Switcher
+ - None
+
+
+ - clipboard
+ - key
+ - menu_ime
+ - space
+
+
+
+
+ - Divided (default)
+ - Centered
+ - Left-aligned
+ - Right-aligned
+
+
+
+ - default
+ - left;back,home,recent;right
+ - left,back,home,recent,right;space;space
+ - space;space;left,back,home,recent,right
+
+
Menu / Keyboard Switcher
-
- Select button to add
-
- Add button
Save
Reset
-
- No home button found
-
- A home button is required to be able to navigate this device. Please add a home button before saving.
-
Adjust button width
Clipboard
-
- The Clipboard allows items to be dragged directly to the clipboard. Items can also be dragged directly out of the clipboard when present.
-
Custom navigation button
Keycode
-
- Keycode buttons allow keyboard keys to
- be added to the Navigation Bar. When pressed they emulate the selected
- keyboard key. First the key must be selected for the button, followed
- by an image to be shown on the button.
-
-
- Select Keyboard Button
-
-
- Preview
+
+ Icon
Drag to add tiles
diff --git a/packages/SystemUI/res/xml/nav_bar_tuner.xml b/packages/SystemUI/res/xml/nav_bar_tuner.xml
new file mode 100644
index 0000000000000..6fa8bec3a9376
--- /dev/null
+++ b/packages/SystemUI/res/xml/nav_bar_tuner.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml
index 59a10dabe9671..3c6315b9fcb27 100644
--- a/packages/SystemUI/res/xml/tuner_prefs.xml
+++ b/packages/SystemUI/res/xml/tuner_prefs.xml
@@ -150,12 +150,10 @@
-
() {
+ public void loadAsync(Icon icon) {
+ new AsyncTask() {
@Override
- protected Drawable doInBackground(String... params) {
- return Icon.createWithContentUri(params[0]).loadDrawable(mContext);
+ protected Drawable doInBackground(Icon... params) {
+ return params[0].loadDrawable(mContext);
}
@Override
protected void onPostExecute(Drawable drawable) {
setImageDrawable(drawable);
}
- }.execute(uri);
+ }.execute(icon);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/BetterListPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/BetterListPreference.java
new file mode 100644
index 0000000000000..c9c780aa6a708
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tuner/BetterListPreference.java
@@ -0,0 +1,39 @@
+/*
+ * 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 android.content.Context;
+import android.support.v7.preference.ListPreference;
+import android.util.AttributeSet;
+
+public class BetterListPreference extends ListPreference {
+
+ private CharSequence mSummary;
+
+ public BetterListPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public void setSummary(CharSequence summary) {
+ super.setSummary(summary);
+ mSummary = summary;
+ }
+
+ @Override
+ public CharSequence getSummary() {
+ return mSummary;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java b/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
index ad424590f6635..9593c45abd032 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * 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
@@ -14,590 +14,227 @@
package com.android.systemui.tuner;
-import android.annotation.Nullable;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Fragment;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.res.ColorStateList;
-import android.content.res.Configuration;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Bundle;
-import android.provider.Settings;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.helper.ItemTouchHelper;
-import android.util.TypedValue;
-import android.view.Display;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.Surface;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.SeekBar;
-import android.widget.TextView;
-
-import com.android.systemui.R;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.BACK;
-import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.BUTTON_SEPARATOR;
-import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.CLIPBOARD;
-import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.GRAVITY_SEPARATOR;
-import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.HOME;
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;
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.RECENT;
-import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.SIZE_MOD_END;
-import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.SIZE_MOD_START;
import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.extractButton;
-import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.extractSize;
+import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.extractImage;
+import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.extractKeycode;
-public class NavBarTuner extends Fragment implements TunerService.Tunable {
+import android.annotation.Nullable;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.res.Resources;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v7.preference.DropDownPreference;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.Preference.OnPreferenceChangeListener;
+import android.support.v7.preference.Preference.OnPreferenceClickListener;
+import android.support.v7.preference.PreferenceCategory;
+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;
- private static final int SAVE = Menu.FIRST + 1;
- private static final int RESET = Menu.FIRST + 2;
- private static final int READ_REQUEST = 42;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.NavigationBarInflaterView;
+import com.android.systemui.tuner.TunerService.Tunable;
- private static final float PREVIEW_SCALE = .95f;
- private static final float PREVIEW_SCALE_LANDSCAPE = .75f;
+import java.util.ArrayList;
- private NavBarAdapter mNavBarAdapter;
- private PreviewNavInflater mPreview;
+public class NavBarTuner extends PreferenceFragment {
+
+ 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.drawable.ic_add,
+ R.drawable.ic_remove,
+ R.drawable.ic_left,
+ R.drawable.ic_right,
+ R.drawable.ic_menu,
+ };
+
+ private final ArrayList mTunables = new ArrayList<>();
+ private Handler mHandler;
@Override
- public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
- Bundle savedInstanceState) {
- final View view = inflater.inflate(R.layout.nav_bar_tuner, container, false);
- inflatePreview((ViewGroup) view.findViewById(R.id.nav_preview_frame));
- return view;
- }
-
- private void inflatePreview(ViewGroup view) {
- Display display = getActivity().getWindowManager().getDefaultDisplay();
- boolean isRotated = display.getRotation() == Surface.ROTATION_90
- || display.getRotation() == Surface.ROTATION_270;
-
- Configuration config = new Configuration(getContext().getResources().getConfiguration());
- boolean isPhoneLandscape = isRotated && (config.smallestScreenWidthDp < 600);
- final float scale = isPhoneLandscape ? PREVIEW_SCALE_LANDSCAPE : PREVIEW_SCALE;
- config.densityDpi = (int) (config.densityDpi * scale);
-
- mPreview = (PreviewNavInflater) LayoutInflater.from(getContext().createConfigurationContext(
- config)).inflate(R.layout.nav_bar_tuner_inflater, view, false);
- final ViewGroup.LayoutParams layoutParams = mPreview.getLayoutParams();
- layoutParams.width = (int) ((isPhoneLandscape ? display.getHeight() : display.getWidth())
- * scale);
- // Not sure why, but the height dimen is not being scaled with the dp, set it manually
- // for now.
- layoutParams.height = (int) (layoutParams.height * scale);
- if (isPhoneLandscape) {
- int width = layoutParams.width;
- layoutParams.width = layoutParams.height;
- layoutParams.height = width;
- }
- view.addView(mPreview);
-
- if (isRotated) {
- mPreview.findViewById(R.id.rot0).setVisibility(View.GONE);
- final View rot90 = mPreview.findViewById(R.id.rot90);
- } else {
- mPreview.findViewById(R.id.rot90).setVisibility(View.GONE);
- final View rot0 = mPreview.findViewById(R.id.rot0);
- }
- }
-
- private void notifyChanged() {
- mPreview.onTuningChanged(NAV_BAR_VIEWS, mNavBarAdapter.getNavString());
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ mHandler = new Handler();
+ super.onCreate(savedInstanceState);
}
@Override
- public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- RecyclerView recyclerView = (RecyclerView) view.findViewById(android.R.id.list);
- final Context context = getContext();
- recyclerView.setLayoutManager(new LinearLayoutManager(context));
- mNavBarAdapter = new NavBarAdapter(context);
- recyclerView.setAdapter(mNavBarAdapter);
- recyclerView.addItemDecoration(new Dividers(context));
- final ItemTouchHelper itemTouchHelper = new ItemTouchHelper(mNavBarAdapter.mCallbacks);
- mNavBarAdapter.setTouchHelper(itemTouchHelper);
- itemTouchHelper.attachToRecyclerView(recyclerView);
-
- TunerService.get(getContext()).addTunable(this, NAV_BAR_VIEWS);
+ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);
}
@Override
- public void onDestroyView() {
- super.onDestroyView();
- TunerService.get(getContext()).removeTunable(this);
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+ addPreferencesFromResource(R.xml.nav_bar_tuner);
+ bindLayout((ListPreference) findPreference(LAYOUT));
+ bindButton((PreferenceCategory) findPreference(LEFT),
+ NAV_BAR_LEFT, NAVSPACE);
+ bindButton((PreferenceCategory) findPreference(RIGHT),
+ NAV_BAR_RIGHT, MENU_IME);
}
@Override
- public void onTuningChanged(String key, String navLayout) {
- if (!NAV_BAR_VIEWS.equals(key)) return;
- Context context = getContext();
- if (navLayout == null) {
- navLayout = context.getString(R.string.config_navBarLayout);
- }
- String[] views = navLayout.split(GRAVITY_SEPARATOR);
- String[] groups = new String[] { NavBarAdapter.START, NavBarAdapter.CENTER,
- NavBarAdapter.END};
- CharSequence[] groupLabels = new String[] { getString(R.string.start),
- getString(R.string.center), getString(R.string.end) };
- mNavBarAdapter.clear();
- for (int i = 0; i < 3; i++) {
- mNavBarAdapter.addButton(groups[i], groupLabels[i]);
- for (String button : views[i].split(BUTTON_SEPARATOR)) {
- mNavBarAdapter.addButton(button, getLabel(button, context));
+ public void onDestroy() {
+ super.onDestroy();
+ mTunables.forEach(t -> TunerService.get(getContext()).removeTunable(t));
+ }
+
+ private void addTunable(Tunable tunable, String... keys) {
+ mTunables.add(tunable);
+ TunerService.get(getContext()).addTunable(tunable, keys);
+ }
+
+ private void bindLayout(ListPreference preference) {
+ addTunable((key, newValue) -> mHandler.post(() -> {
+ String val = newValue;
+ if (val == null) {
+ val = "default";
}
- }
- mNavBarAdapter.addButton(NavBarAdapter.ADD, getString(R.string.add_button));
- setHasOptionsMenu(true);
+ preference.setValue(val);
+ }), NAV_BAR_VIEWS);
+ preference.setOnPreferenceChangeListener((preference1, newValue) -> {
+ String val = (String) newValue;
+ if ("default".equals(val)) val = null;
+ TunerService.get(getContext()).setValue(NAV_BAR_VIEWS, val);
+ return true;
+ });
}
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- super.onCreateOptionsMenu(menu, inflater);
- // TODO: Show save button conditionally, only when there are changes.
- menu.add(Menu.NONE, SAVE, Menu.NONE, getString(R.string.save))
- .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
- menu.add(Menu.NONE, RESET, Menu.NONE, getString(R.string.reset));
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if (item.getItemId() == SAVE) {
- if (!mNavBarAdapter.hasHomeButton()) {
- new AlertDialog.Builder(getContext())
- .setTitle(R.string.no_home_title)
- .setMessage(R.string.no_home_message)
- .setPositiveButton(android.R.string.ok, null)
- .show();
+ private void bindButton(PreferenceCategory parent, String setting, String def) {
+ String k = parent.getKey();
+ DropDownPreference type = (DropDownPreference) 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 {
- Settings.Secure.putString(getContext().getContentResolver(),
- NAV_BAR_VIEWS, mNavBarAdapter.getNavString());
+ type.setValue(button);
+ keycode.setVisible(false);
+ icon.setVisible(false);
}
- return true;
- } else if (item.getItemId() == RESET) {
- Settings.Secure.putString(getContext().getContentResolver(),
- NAV_BAR_VIEWS, null);
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
- private static CharSequence getLabel(String button, Context context) {
- if (button.startsWith(HOME)) {
- return context.getString(R.string.accessibility_home);
- } else if (button.startsWith(BACK)) {
- return context.getString(R.string.accessibility_back);
- } else if (button.startsWith(RECENT)) {
- return context.getString(R.string.accessibility_recent);
- } else if (button.startsWith(NAVSPACE)) {
- return context.getString(R.string.space);
- } else if (button.startsWith(MENU_IME)) {
- return context.getString(R.string.menu_ime);
- } else if (button.startsWith(CLIPBOARD)) {
- return context.getString(R.string.clipboard);
- } else if (button.startsWith(KEY)) {
- return context.getString(R.string.keycode);
- }
- return button;
- }
-
- private static class Holder extends RecyclerView.ViewHolder {
- private TextView title;
-
- public Holder(View itemView) {
- super(itemView);
- title = (TextView) itemView.findViewById(android.R.id.title);
- }
- }
-
- private static class Dividers extends RecyclerView.ItemDecoration {
- private final Drawable mDivider;
-
- public Dividers(Context context) {
- TypedValue value = new TypedValue();
- context.getTheme().resolveAttribute(android.R.attr.listDivider, value, true);
- mDivider = context.getDrawable(value.resourceId);
- }
-
- @Override
- public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
- super.onDraw(c, parent, state);
- final int left = parent.getPaddingLeft();
- final int right = parent.getWidth() - parent.getPaddingRight();
-
- final int childCount = parent.getChildCount();
- for (int i = 0; i < childCount; i++) {
- final View child = parent.getChildAt(i);
- final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
- .getLayoutParams();
- final int top = child.getBottom() + params.bottomMargin;
- final int bottom = top + mDivider.getIntrinsicHeight();
- mDivider.setBounds(left, top, right, bottom);
- mDivider.draw(c);
- }
- }
- }
-
- private void selectImage() {
- startActivityForResult(KeycodeSelectionHelper.getSelectImageIntent(), READ_REQUEST);
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == READ_REQUEST && resultCode == Activity.RESULT_OK && data != null) {
- final Uri uri = data.getData();
- final int takeFlags = data.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION);
- getContext().getContentResolver().takePersistableUriPermission(uri, takeFlags);
- mNavBarAdapter.onImageSelected(uri);
- } else {
- super.onActivityResult(requestCode, resultCode, data);
- }
- }
-
- private class NavBarAdapter extends RecyclerView.Adapter
- implements View.OnClickListener {
-
- private static final String START = "start";
- private static final String CENTER = "center";
- private static final String END = "end";
- private static final String ADD = "add";
-
- private static final int ADD_ID = 0;
- private static final int BUTTON_ID = 1;
- private static final int CATEGORY_ID = 2;
-
- private List mButtons = new ArrayList<>();
- private List mLabels = new ArrayList<>();
- private int mCategoryLayout;
- private int mButtonLayout;
- private ItemTouchHelper mTouchHelper;
-
- // Stored keycode while we wait for image selection on a KEY.
- private int mKeycode;
-
- public NavBarAdapter(Context context) {
- TypedArray attrs = context.getTheme().obtainStyledAttributes(null,
- android.R.styleable.Preference, android.R.attr.preferenceStyle, 0);
- mButtonLayout = attrs.getResourceId(android.R.styleable.Preference_layout, 0);
- attrs = context.getTheme().obtainStyledAttributes(null,
- android.R.styleable.Preference, android.R.attr.preferenceCategoryStyle, 0);
- mCategoryLayout = attrs.getResourceId(android.R.styleable.Preference_layout, 0);
- }
-
- public void setTouchHelper(ItemTouchHelper itemTouchHelper) {
- mTouchHelper = itemTouchHelper;
- }
-
- public void clear() {
- mButtons.clear();
- mLabels.clear();
- notifyDataSetChanged();
- }
-
- public void addButton(String button, CharSequence label) {
- mButtons.add(button);
- mLabels.add(label);
- notifyItemInserted(mLabels.size() - 1);
- notifyChanged();
- }
-
- public boolean hasHomeButton() {
- final int N = mButtons.size();
- for (int i = 0; i < N; i++) {
- if (mButtons.get(i).startsWith(HOME)) {
- return true;
- }
- }
- return false;
- }
-
- public String getNavString() {
- StringBuilder builder = new StringBuilder();
- for (int i = 1; i < mButtons.size() - 1; i++) {
- String button = mButtons.get(i);
- if (button.equals(CENTER) || button.equals(END)) {
- if (builder.length() == 0 || builder.toString().endsWith(GRAVITY_SEPARATOR)) {
- // No start or center buttons, fill with a space.
- builder.append(NAVSPACE);
- }
- builder.append(GRAVITY_SEPARATOR);
- continue;
- } else if (builder.length() != 0 && !builder.toString().endsWith(
- GRAVITY_SEPARATOR)) {
- builder.append(BUTTON_SEPARATOR);
- }
- builder.append(button);
- }
- if (builder.toString().endsWith(GRAVITY_SEPARATOR)) {
- // No end buttons, fill with space.
- builder.append(NAVSPACE);
- }
- return builder.toString();
- }
-
- @Override
- public int getItemViewType(int position) {
- String button = mButtons.get(position);
- if (button.equals(START) || button.equals(CENTER) || button.equals(END)) {
- return CATEGORY_ID;
- }
- if (button.equals(ADD)) {
- return ADD_ID;
- }
- return BUTTON_ID;
- }
-
- @Override
- public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
- final Context context = parent.getContext();
- final LayoutInflater inflater = LayoutInflater.from(context);
- final View view = inflater.inflate(getLayoutId(viewType), parent, false);
- if (viewType == BUTTON_ID) {
- inflater.inflate(R.layout.nav_control_widget,
- (ViewGroup) view.findViewById(android.R.id.widget_frame));
- }
- return new Holder(view);
- }
-
- private int getLayoutId(int viewType) {
- if (viewType == CATEGORY_ID) {
- return mCategoryLayout;
- }
- return mButtonLayout;
- }
-
- @Override
- public void onBindViewHolder(Holder holder, int position) {
- holder.title.setText(mLabels.get(position));
- if (holder.getItemViewType() == BUTTON_ID) {
- bindButton(holder, position);
- } else if (holder.getItemViewType() == ADD_ID) {
- bindAdd(holder);
- }
- }
-
- private void bindAdd(Holder holder) {
- TypedValue value = new TypedValue();
- final Context context = holder.itemView.getContext();
- context.getTheme().resolveAttribute(android.R.attr.colorAccent, value, true);
- final ImageView icon = (ImageView) holder.itemView.findViewById(android.R.id.icon);
- icon.setImageResource(R.drawable.ic_add);
- icon.setImageTintList(ColorStateList.valueOf(context.getColor(value.resourceId)));
- holder.itemView.findViewById(android.R.id.summary).setVisibility(View.GONE);
- holder.itemView.setClickable(true);
- holder.itemView.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- showAddDialog(v.getContext());
- }
+ }), setting);
+ OnPreferenceChangeListener listener = (preference, newValue) -> {
+ mHandler.post(() -> {
+ setValue(setting, type, keycode, icon);
+ updateSummary(icon);
});
- }
-
- private void bindButton(final Holder holder, int position) {
- holder.itemView.findViewById(android.R.id.icon_frame).setVisibility(View.GONE);
- holder.itemView.findViewById(android.R.id.summary).setVisibility(View.GONE);
- bindClick(holder.itemView.findViewById(R.id.close), holder);
- bindClick(holder.itemView.findViewById(R.id.width), holder);
- holder.itemView.findViewById(R.id.drag).setOnTouchListener(new View.OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- mTouchHelper.startDrag(holder);
- return true;
- }
- });
- }
-
- private void showAddDialog(final Context context) {
- final String[] options = new String[] {
- BACK, HOME, RECENT, MENU_IME, NAVSPACE, CLIPBOARD, KEY,
- };
- final CharSequence[] labels = new CharSequence[options.length];
- for (int i = 0; i < options.length; i++) {
- labels[i] = getLabel(options[i], context);
- }
- new AlertDialog.Builder(context)
- .setTitle(R.string.select_button)
- .setItems(labels, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- if (KEY.equals(options[which])) {
- showKeyDialogs(context);
- } else {
- int index = mButtons.size() - 1;
- showAddedMessage(context, options[which]);
- mButtons.add(index, options[which]);
- mLabels.add(index, labels[which]);
-
- notifyItemInserted(index);
- notifyChanged();
- }
- }
- }).setNegativeButton(android.R.string.cancel, null)
- .show();
- }
-
- private void onImageSelected(Uri uri) {
- int index = mButtons.size() - 1;
- mButtons.add(index, KEY + KEY_CODE_START + mKeycode + KEY_IMAGE_DELIM + uri.toString()
- + KEY_CODE_END);
- mLabels.add(index, getLabel(KEY, getContext()));
-
- notifyItemInserted(index);
- notifyChanged();
- }
-
- private void showKeyDialogs(final Context context) {
- final KeycodeSelectionHelper.OnSelectionComplete listener =
- new KeycodeSelectionHelper.OnSelectionComplete() {
- @Override
- public void onSelectionComplete(int code) {
- mKeycode = code;
- selectImage();
- }
- };
- new AlertDialog.Builder(context)
- .setTitle(R.string.keycode)
- .setMessage(R.string.keycode_description)
- .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- KeycodeSelectionHelper.showKeycodeSelect(context, listener);
- }
- }).show();
- }
-
- private void showAddedMessage(Context context, String button) {
- if (CLIPBOARD.equals(button)) {
- new AlertDialog.Builder(context)
- .setTitle(R.string.clipboard)
- .setMessage(R.string.clipboard_description)
- .setPositiveButton(android.R.string.ok, null)
- .show();
- }
- }
-
- private void bindClick(View view, Holder holder) {
- view.setOnClickListener(this);
- view.setTag(holder);
- }
-
- @Override
- public void onClick(View v) {
- Holder holder = (Holder) v.getTag();
- if (v.getId() == R.id.width) {
- showWidthDialog(holder, v.getContext());
- } else if (v.getId() == R.id.close) {
- int position = holder.getAdapterPosition();
- mButtons.remove(position);
- mLabels.remove(position);
- notifyItemRemoved(position);
- notifyChanged();
- }
- }
-
- private void showWidthDialog(final Holder holder, Context context) {
- final String buttonSpec = mButtons.get(holder.getAdapterPosition());
- float amount = extractSize(buttonSpec);
- final AlertDialog dialog = new AlertDialog.Builder(context)
- .setTitle(R.string.adjust_button_width)
- .setView(R.layout.nav_width_view)
- .setNegativeButton(android.R.string.cancel, null).create();
- dialog.setButton(DialogInterface.BUTTON_POSITIVE,
- context.getString(android.R.string.ok),
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface d, int which) {
- final String button = extractButton(buttonSpec);
- SeekBar seekBar = (SeekBar) dialog.findViewById(R.id.seekbar);
- if (seekBar.getProgress() == 75) {
- mButtons.set(holder.getAdapterPosition(), button);
- } else {
- float amount = (seekBar.getProgress() + 25) / 100f;
- mButtons.set(holder.getAdapterPosition(), button
- + SIZE_MOD_START + amount + SIZE_MOD_END);
- }
- notifyChanged();
- }
- });
- dialog.show();
- SeekBar seekBar = (SeekBar) dialog.findViewById(R.id.seekbar);
- // Range is .25 - 1.75.
- seekBar.setMax(150);
- seekBar.setProgress((int) ((amount - .25f) * 100));
- }
-
- @Override
- public int getItemCount() {
- return mButtons.size();
- }
-
- private final ItemTouchHelper.Callback mCallbacks = new ItemTouchHelper.Callback() {
- @Override
- public boolean isLongPressDragEnabled() {
- return false;
- }
-
- @Override
- public boolean isItemViewSwipeEnabled() {
- return false;
- }
-
- @Override
- public int getMovementFlags(RecyclerView recyclerView,
- RecyclerView.ViewHolder viewHolder) {
- if (viewHolder.getItemViewType() != BUTTON_ID) {
- return makeMovementFlags(0, 0);
- }
- int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
- return makeMovementFlags(dragFlags, 0);
- }
-
- @Override
- public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,
- RecyclerView.ViewHolder target) {
- int from = viewHolder.getAdapterPosition();
- int to = target.getAdapterPosition();
- if (to == 0) {
- // Can't go above the top.
- return false;
- }
- move(from, to, mButtons);
- move(from, to, mLabels);
- notifyChanged();
- notifyItemMoved(from, to);
- return true;
- }
-
- private void move(int from, int to, List list) {
- list.add(from > to ? to : to + 1, list.get(from));
- list.remove(from > to ? from + 1 : from);
- }
-
- @Override
- public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
- // Don't care.
- }
+ 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);
+ builder.append(" ", span, 0);
+ icon.setSummary(builder);
+ } catch (Exception e) {
+ Log.d("NavButton", "Problem with summary", e);
+ icon.setSummary(null);
+ }
+ }
+
+ private void setValue(String setting, DropDownPreference 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;
+ }
+ TunerService.get(getContext()).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])
+ .loadDrawable(getContext());
+ d.setTint(Color.BLACK);
+ d.setBounds(0, 0, size, size);
+ ImageSpan span = new ImageSpan(d);
+ builder.append(" ", span, 0);
+ labels[i] = builder;
+ values[i] = getContext().getPackageName() + "/" + ICONS[i];
+ }
+ icon.setEntries(labels);
+ icon.setEntryValues(values);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
index 565ac08f92ee4..fb94061f40935 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
@@ -33,6 +33,7 @@ import android.os.Looper;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
+import android.provider.Settings.Secure;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -126,6 +127,12 @@ public class TunerService extends SystemUI {
return Settings.Secure.getIntForUser(mContentResolver, setting, def, mCurrentUser);
}
+ public String getValue(String setting, String def) {
+ String ret = Secure.getStringForUser(mContentResolver, setting, mCurrentUser);
+ if (ret == null) return def;
+ return ret;
+ }
+
public void setValue(String setting, int value) {
Settings.Secure.putIntForUser(mContentResolver, setting, value, mCurrentUser);
}