From c2d2a6951ca0791515ba4f0f3d9ca94657a3f0be Mon Sep 17 00:00:00 2001 From: Danny Baumann Date: Sat, 22 Jun 2013 14:14:58 +0200 Subject: Make navigation bar ready for per-user configuration. Also clean it up a bit. Change-Id: Ic10bd161fce53bf30048a0cb927dcf1e2bfa7774 --- .../res/layout/navigation_bar_edit_menu_item.xml | 44 ++ .../systemui/statusbar/NavigationButtons.java | 5 + .../systemui/statusbar/phone/NavbarEditor.java | 583 ++++++++++----------- .../statusbar/phone/NavigationBarView.java | 92 ++-- .../systemui/statusbar/phone/PhoneStatusBar.java | 9 +- .../systemui/statusbar/policy/KeyButtonView.java | 71 ++- 6 files changed, 424 insertions(+), 380 deletions(-) create mode 100644 packages/SystemUI/res/layout/navigation_bar_edit_menu_item.xml (limited to 'packages/SystemUI') diff --git a/packages/SystemUI/res/layout/navigation_bar_edit_menu_item.xml b/packages/SystemUI/res/layout/navigation_bar_edit_menu_item.xml new file mode 100644 index 0000000..2d914c3 --- /dev/null +++ b/packages/SystemUI/res/layout/navigation_bar_edit_menu_item.xml @@ -0,0 +1,44 @@ + + + + + + + + + + diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NavigationButtons.java b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationButtons.java index c8b1252..794a845 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NavigationButtons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationButtons.java @@ -97,6 +97,11 @@ public class NavigationButtons { sideResource = sR; this.key = key; } + + @Override + public String toString() { + return "ButtonInfo[" + key + "]"; + } } // Available buttons string constants diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavbarEditor.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavbarEditor.java index 4f4d407..9de38ad 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavbarEditor.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavbarEditor.java @@ -1,31 +1,38 @@ -package com.android.systemui.statusbar.phone; +/* + * Copyright (C) 2012 The CyanogenMod 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. + */ -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; +package com.android.systemui.statusbar.phone; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; -import android.content.res.Configuration; -import android.database.DataSetObserver; -import android.graphics.Color; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffColorFilter; import android.provider.Settings; import android.util.DisplayMetrics; import android.view.DisplayInfo; import android.view.HapticFeedbackConstants; -import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; -import android.view.View.OnTouchListener; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.WindowManager; +import android.widget.ArrayAdapter; import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.ListAdapter; import android.widget.TextView; import com.android.internal.util.ArrayUtils; @@ -34,364 +41,363 @@ import com.android.systemui.statusbar.NavigationButtons; import com.android.systemui.statusbar.NavigationButtons.ButtonInfo; import com.android.systemui.statusbar.policy.KeyButtonView; +import java.util.ArrayList; +import java.util.Collections; + /** * Handles the editing of the navigation bar * @author Danesh M * @hide */ -public class NavbarEditor implements OnTouchListener { - +public class NavbarEditor implements View.OnTouchListener { /** * Holds reference to all assignable button ids. * Hold this in sync with {@link NavigationButtons#BUTTON_COUNT} */ - ArrayList mIds = new ArrayList(Arrays.asList(R.id.one, R.id.two, R.id.three, - R.id.four, R.id.five,R.id.six)); + private static final int[] BUTTON_IDS = + { R.id.one, R.id.two, R.id.three, R.id.four, R.id.five, R.id.six }; /** - * Subset of mIds, to differentiate small/side buttons + * Subset of BUTON_IDS, to differentiate small/side buttons * since they can be assigned additional functionality. * Hold this in sync with {@link NavigationButtons#BUTTON_IS_SMALL} */ - public static final int[] smallButtonIds = {R.id.one, R.id.six}; + private static final int[] SMALL_BUTTON_IDS = { R.id.one, R.id.six }; - protected static int visibleCount = 4; - private static Boolean mIsDevicePhone = null; + // holds the button views in the order they currently appear on screen + private final ArrayList mButtonViews; - /** - * Holds reference to the parent/root of the inflated view - */ - private ViewGroup mParent; + private Context mContext; + private static Boolean sIsDevicePhone = null; + private boolean mInEditMode = false; - /** - * Button chooser dialog - */ - AlertDialog mDialog; + // Holds reference to the parent/root of the inflated view + private View mParent; + + // Button chooser dialog + private AlertDialog mDialog; + + // true == we're in landscape mode + private boolean mVertical; + // true == we're currently checking for long press + private boolean mLongPressed; + // start point of the current drag operation + private float mDragOrigin; + + // just to avoid reallocations + private static final int[] sLocation = new int[2]; /** - * mVertical = Whether we're in landscape mode - * mLongPressed = Whether the longpress runnable was activated. + * Longpress runnable to assign buttons in edit mode */ - boolean mVertical,mLongPressed; - - private Context mContext; + private Runnable mCheckLongPress = new Runnable() { + public void run() { + if (mInEditMode) { + mLongPressed = true; + mParent.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY); + } + } + }; - public NavbarEditor (ViewGroup parent, Boolean orientation) { + public NavbarEditor (View parent, boolean orientation) { + mContext = parent.getContext(); mParent = parent; mVertical = orientation; - mContext = parent.getContext(); + + mButtonViews = new ArrayList(); + for (int id : BUTTON_IDS) { + mButtonViews.add((KeyButtonView) mParent.findViewById(id)); + } } - /** - * Set the button listeners to this - * class when in edit mode - */ - protected void setupListeners() { - for (int id : mIds) { - mParent.findViewById(id).setOnTouchListener(this); + public void setEditMode(boolean editMode) { + mInEditMode = editMode; + for (Integer id : BUTTON_IDS) { + KeyButtonView button = (KeyButtonView) mParent.findViewById(id); + if (button != null) { + button.setEditMode(editMode); + button.setOnTouchListener(editMode ? this : null); + } + } + if (!editMode && mDialog != null && mDialog.isShowing()) { + mDialog.dismiss(); } } + public static boolean isDevicePhone(Context context) { + if (sIsDevicePhone == null) { + WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + DisplayInfo outDisplayInfo = new DisplayInfo(); + + wm.getDefaultDisplay().getDisplayInfo(outDisplayInfo); + + int shortSize = Math.min(outDisplayInfo.logicalHeight, outDisplayInfo.logicalWidth); + int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / outDisplayInfo.logicalDensityDpi; + + // 0-599dp: "phone" UI with a separate status & navigation bar + sIsDevicePhone = shortSizeDp < 600; + } + + return sIsDevicePhone; + } + /** - * Find intersecting views in mIds + * Find intersecting view in mButtonViews * @param pos - pointer location * @param v - view being dragged - * @return array index in mIds of view intersecting + * @return intersecting view or null */ - private int findInterceptingViewIndex(float pos, View v) { - int location[] = new int[2]; - for (int cc = 0; cc < mIds.size(); cc++) { - if (!ArrayUtils.contains(smallButtonIds,mIds.get(cc))) { - View tmpV = mParent.findViewById(mIds.get(cc)); - tmpV.getLocationOnScreen(location); - if (tmpV == v) { - continue; - } else if (!mVertical && (pos > (location[0]+v.getWidth()/4) && pos < location[0]+v.getWidth())) { - return cc; - } else if (mVertical && (pos > (location[1]+v.getHeight()/4) && pos < location[1]+v.getHeight())) { - return cc; - } + private View findInterceptingView(float pos, View v) { + for (KeyButtonView otherView : mButtonViews) { + if (otherView == v) { + continue; } - } - return -1; - } - /** - * Longpress runnable to assign buttons in edit mode - */ - Runnable mCheckLongPress = new Runnable() { - public void run() { - if (NavigationBarView.getEditMode()) { - mLongPressed = true; - mParent.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY); - return; + if (ArrayUtils.contains(SMALL_BUTTON_IDS, otherView.getId())) { + continue; } - } - }; - protected static boolean isDevicePhone(Context con) { - if (mIsDevicePhone == null) { - WindowManager wm = (WindowManager)con.getSystemService(Context.WINDOW_SERVICE); - DisplayInfo outDisplayInfo = new DisplayInfo(); - wm.getDefaultDisplay().getDisplayInfo(outDisplayInfo); - int shortSize = Math.min(outDisplayInfo.logicalHeight, outDisplayInfo.logicalWidth); - int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / outDisplayInfo.logicalDensityDpi; - if (shortSizeDp < 600) { - // 0-599dp: "phone" UI with a separate status & navigation bar - mIsDevicePhone = true; - } else { - mIsDevicePhone = false; + otherView.getLocationOnScreen(sLocation); + float otherPos = sLocation[mVertical ? 1 : 0]; + float otherDimension = mVertical ? v.getHeight() : v.getWidth(); + + if (pos > (otherPos + otherDimension / 4) && pos < (otherPos + otherDimension)) { + return otherView; } } - return mIsDevicePhone; + return null; } @Override public boolean onTouch(final View view, MotionEvent event) { - if (!NavigationBarView.getEditMode() || (mDialog != null && mDialog.isShowing())) { + if (!mInEditMode || (mDialog != null && mDialog.isShowing())) { return false; } - float curPos = 0; - if (!mVertical) { - curPos = event.getRawX(); - } else { - curPos = event.getRawY(); - } + if (event.getAction() == MotionEvent.ACTION_DOWN) { - int screenLoc[] = new int[2]; view.setPressed(true); - view.getLocationOnScreen(screenLoc); - // Store the starting view position in the parent's tag - if (!mVertical) { - mParent.setTag(Float.valueOf(screenLoc[0])); - } else { - mParent.setTag(Float.valueOf(screenLoc[1])); - } + view.getLocationOnScreen(sLocation); + mDragOrigin = sLocation[mVertical ? 1 : 0]; view.postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout()); } else if (event.getAction() == MotionEvent.ACTION_MOVE) { view.setPressed(false); - if (!mLongPressed || ArrayUtils.contains(smallButtonIds, view.getId())) { + + if (!mLongPressed || ArrayUtils.contains(SMALL_BUTTON_IDS, view.getId())) { return false; } - view.bringToFront(); + ViewGroup viewParent = (ViewGroup) view.getParent(); - float buttonSize = 0; - if (!mVertical) { - buttonSize = view.getWidth(); - } else { - buttonSize = view.getHeight(); - } + float pos = mVertical ? event.getRawY() : event.getRawX(); + float buttonSize = mVertical ? view.getHeight() : view.getWidth(); + float min = mVertical ? viewParent.getTop() : (viewParent.getLeft() - buttonSize / 2); + float max = mVertical ? (viewParent.getTop() + viewParent.getHeight()) + : (viewParent.getLeft() + viewParent.getWidth()); + // Prevents user from dragging view outside of bounds - if ((!mVertical && ((curPos) > (viewParent.getWidth() + viewParent.getLeft()) || (curPos - buttonSize/2 <= viewParent.getLeft()))) || - (mVertical && ((curPos > (viewParent.getHeight() + viewParent.getTop())) || (curPos < viewParent.getTop())))) { + if (pos < min || pos > max) { return false; } if (!mVertical) { - view.setX(curPos - viewParent.getLeft() - buttonSize/2); + view.setX(pos - viewParent.getLeft() - buttonSize / 2); } else { - view.setY(curPos - viewParent.getTop() - buttonSize/2); + view.setY(pos - viewParent.getTop() - buttonSize / 2); } - int affectedViewPosition = findInterceptingViewIndex(curPos, view); - if (affectedViewPosition == -1) { + View affectedView = findInterceptingView(pos, view); + if (affectedView == null) { return false; } - switchId(mIds.indexOf(view.getId()), affectedViewPosition, view); - } else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) { + switchId(affectedView, view); + } else if (event.getAction() == MotionEvent.ACTION_UP + || event.getAction() == MotionEvent.ACTION_CANCEL) { view.setPressed(false); view.removeCallbacks(mCheckLongPress); - if (!mLongPressed && !view.getTag().equals("home")) { - final ButtonAdapter list = new ButtonAdapter(ArrayUtils.contains(smallButtonIds, view.getId()) ? true : false); - AlertDialog.Builder builder = new AlertDialog.Builder(mContext); - builder.setTitle(mContext.getString(R.string.navbar_dialog_title)); - builder.setAdapter(list, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - ((KeyButtonView) view).setInfo((ButtonInfo) list.getItem(which), mVertical); - } - }) - .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - dialog.cancel(); - } - }); + + if (!mLongPressed && !view.getTag().equals(NavigationButtons.HOME)) { + final boolean isSmallButton = ArrayUtils.contains(SMALL_BUTTON_IDS, view.getId()); + final ButtonAdapter list = new ButtonAdapter(mContext, mButtonViews, isSmallButton); + + AlertDialog.Builder builder = new AlertDialog.Builder(mContext) + .setTitle(mContext.getString(R.string.navbar_dialog_title)) + .setAdapter(list, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + KeyButtonView button = (KeyButtonView) view; + ButtonInfo info = (ButtonInfo) list.getItem(which); + + button.setInfo(info, mVertical, isSmallButton); + } + }) + .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + } + }); + mDialog = builder.create(); - mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); + mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG); mDialog.setCanceledOnTouchOutside(false); mDialog.show(); - mLongPressed=false; - return true; - } - mLongPressed=false; - // Reset the dragged view to its original location - ViewGroup vParent = (ViewGroup) view.getParent(); - if (!mVertical) { - view.setX((Float) mParent.getTag() - vParent.getLeft()); } else { - view.setY((Float) mParent.getTag() - vParent.getTop()); + // Reset the dragged view to its original location + ViewGroup parent = (ViewGroup) view.getParent(); + + if (!mVertical) { + view.setX(mDragOrigin - parent.getLeft()); + } else { + view.setY(mDragOrigin - parent.getTop()); + } } + mLongPressed = false; } return true; } /** * Switches positions of two views and - * updates their mIds entry - * @param to - index for new position in mIds - * @param from - index for old position in mIds + * updates their mButtonViews entry + * @param targetView - view to be replaced * @param view - view being dragged */ - private void switchId(int to, int from, View view) { - View tView = mParent.findViewById(mIds.get(from)); - int screenLoc[] = new int[2]; - tView.getLocationOnScreen(screenLoc); - ViewGroup a = (ViewGroup) view.getParent(); + private void switchId(View targetView, View view) { + ViewGroup parent = (ViewGroup) view.getParent(); + + targetView.getLocationOnScreen(sLocation); if (!mVertical) { - tView.setX((Float) mParent.getTag() - a.getLeft()); - mParent.setTag(Float.valueOf(screenLoc[0])); + targetView.setX(mDragOrigin - parent.getLeft()); + mDragOrigin = sLocation[0]; } else { - tView.setY((Float) mParent.getTag() - a.getTop()); - mParent.setTag(Float.valueOf(screenLoc[1])); + targetView.setY(mDragOrigin - parent.getTop()); + mDragOrigin = sLocation[1]; } - Collections.swap(mIds,to,from); + + int targetIndex = mButtonViews.indexOf(targetView); + int draggedIndex = mButtonViews.indexOf(view); + Collections.swap(mButtonViews, draggedIndex, targetIndex); } /** * Saves the current key arrangement * to the settings provider */ - @SuppressWarnings("unchecked") protected void saveKeys() { - ((ViewGroup) mParent.findViewById(R.id.mid_nav_buttons)).setLayoutTransition(null); ButtonInfo[] buttons = new ButtonInfo[NavigationButtons.SLOT_COUNT]; - List idMap = (List) mIds.clone(); - if (mVertical) Collections.reverse(idMap); for (int i = 0; i < NavigationButtons.SLOT_COUNT; i++) { - buttons[i] = (ButtonInfo) mParent.findViewById(idMap.get(i)).getTag(); + int idIndex = mVertical ? NavigationButtons.SLOT_COUNT - i : i; + buttons[i] = (ButtonInfo) mButtonViews.get(idIndex).getTag(); } NavigationButtons.storeButtonMap(mContext, buttons); } /** - * Reinflates navigation bar on demand - * base on current orientation - */ - protected void reInflate() { - ((ViewGroup)mParent).removeAllViews(); - if (mVertical) { - View.inflate(mContext, R.layout.mid_navigation_bar_land, (ViewGroup) mParent); - } else { - View.inflate(mContext, R.layout.mid_navigation_bar_port, (ViewGroup) mParent); - } - } - - /** * Updates the buttons according to the * key arrangement stored in settings provider */ - @SuppressWarnings("unchecked") protected void updateKeys() { ButtonInfo[] buttons = NavigationButtons.loadButtonMap(mContext); - int cc = 0; - ArrayList idMap = (ArrayList) mIds.clone(); - if (mVertical) Collections.reverse(idMap); - visibleCount = 0; - for (ButtonInfo bi : buttons) { - KeyButtonView curView = (KeyButtonView) mParent.findViewById(idMap.get(cc)); - boolean isSmallButton = NavigationButtons.IS_SLOT_SMALL[cc]; - curView.setInfo(bi, mVertical); - if (!curView.getTag().equals(NavigationButtons.EMPTY) && !isSmallButton) { + int visibleCount = 0; + + for (int i = 0; i < buttons.length; i++) { + int id = BUTTON_IDS[i]; + ButtonInfo info = buttons[i]; + KeyButtonView button = (KeyButtonView) mParent.findViewById(id); + boolean isSmallButton = NavigationButtons.IS_SLOT_SMALL[i]; + + button.setInfo(info, mVertical, isSmallButton); + if (!info.equals(NavigationButtons.EMPTY) && !isSmallButton) { visibleCount++; } - cc++; + + button.setTranslationX(0); + mButtonViews.set(i, button); } + if (isDevicePhone(mContext)) { - adjustPadding(); + adjustPadding(visibleCount); } + updateLowLights(visibleCount); } /** * Accommodates the padding between keys based on * number of keys in use. */ - private void adjustPadding() { + private void adjustPadding(int visibleCount) { ViewGroup viewParent = (ViewGroup) mParent.findViewById(R.id.mid_nav_buttons); - int sCount = visibleCount; - for (int v = 0; v < viewParent.getChildCount();v++) { - View cView = viewParent.getChildAt(v); - if (cView instanceof KeyButtonView) { - View nextPadding = viewParent.getChildAt(v+1); - if (nextPadding != null) { - View nextKey = viewParent.getChildAt(v+2); - ButtonInfo nextBi = NavigationButtons.EMPTY; - if (nextKey != null) { - nextBi = (ButtonInfo) nextKey.getTag(); - } - ButtonInfo curBi = (ButtonInfo) cView.getTag(); - if (nextKey != null && nextBi != null - && curBi != null && curBi != NavigationButtons.EMPTY) { - if (nextBi != NavigationButtons.EMPTY){ - nextPadding.setVisibility(View.VISIBLE); - } else { - if (sCount > 1) { - nextPadding.setVisibility(View.VISIBLE); - } else { - nextPadding.setVisibility(View.GONE); - } - } - sCount--; - } else { - nextPadding.setVisibility(View.GONE); - } + int totalViews = viewParent.getChildCount(); + + for (int v = 0; v < totalViews; v++) { + View currentKey = viewParent.getChildAt(v); + if (!(currentKey instanceof KeyButtonView)) { + continue; + } + View nextPadding = viewParent.getChildAt(v + 1); + if (nextPadding == null) { + continue; + } + + View nextKey = viewParent.getChildAt(v + 2); + ButtonInfo nextInfo = nextKey == null ? null : (ButtonInfo) nextKey.getTag(); + ButtonInfo currentInfo = (ButtonInfo) currentKey.getTag(); + + if (nextInfo != null && currentInfo != null && currentInfo != NavigationButtons.EMPTY) { + if (nextInfo != NavigationButtons.EMPTY || visibleCount > 1) { + nextPadding.setVisibility(View.VISIBLE); + } else { + nextPadding.setVisibility(View.GONE); } + visibleCount--; + } else { + nextPadding.setVisibility(View.GONE); } } } - protected void updateLowLights(View current) { - ViewGroup lowLights = (ViewGroup) current.findViewById(R.id.lights_out); + protected void updateLowLights(int visibleCount) { + ViewGroup lowLights = (ViewGroup) mParent.findViewById(R.id.lights_out); int totalViews = lowLights.getChildCount(); - int visibleCount = NavbarEditor.visibleCount; - for (int v = 0;v 0 && blank != null) { - blank.setVisibility(View.VISIBLE); - } else if (blank != null) { - blank.setVisibility(View.GONE); - } - } + + for (int v = 0;v < totalViews; v++) { + View currentView = lowLights.getChildAt(v); + if (!(currentView instanceof ImageView)) { + continue; + } + + if (visibleCount <= 0) { + currentView.setVisibility(View.GONE); + } else { + currentView.setVisibility(View.VISIBLE); + visibleCount--; + } + + View blank = lowLights.getChildAt(v + 1); + if (blank != null) { + blank.setVisibility(visibleCount > 0 ? View.VISIBLE : View.GONE); } } } - private class ButtonAdapter implements ListAdapter { - - /** - * Already assigned items - */ - ArrayList takenItems; - ArrayList items; - LayoutInflater inflater; - - ButtonAdapter (boolean smallButtons) { - inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - takenItems = new ArrayList(); - for (int id : mIds) { - ButtonInfo vTag = (ButtonInfo) mParent.findViewById(id).getTag(); - if (vTag == null || vTag == NavigationButtons.EMPTY) { - continue; + private static class ButtonAdapter extends ArrayAdapter { + private ArrayList mTakenItems; + + public ButtonAdapter(Context context, + ArrayList buttons, boolean smallButtons) { + super(context, R.layout.navigation_bar_edit_menu_item, R.id.key_text, + buildItems(smallButtons)); + + mTakenItems = new ArrayList(); + for (KeyButtonView button : buttons) { + ButtonInfo info = (ButtonInfo) button.getTag(); + if (info != null && info != NavigationButtons.EMPTY) { + mTakenItems.add(info); } - takenItems.add(vTag); } - items = new ArrayList(NavigationButtons.BUTTON_MAP.values()); + } + + private static ArrayList buildItems(boolean smallButtons) { + ArrayList items = + new ArrayList(NavigationButtons.BUTTON_MAP.values()); + // home button is not assignable items.remove(NavigationButtons.HOME); // menu buttons can only be assigned to side buttons @@ -401,64 +407,26 @@ public class NavbarEditor implements OnTouchListener { } else { items.remove(NavigationButtons.MENU_BIG); } - } - - @Override - public int getCount() { - return items.size(); - } - @Override - public Object getItem(int arg0) { - return items.get(arg0); - } - - @Override - public long getItemId(int arg0) { - return 0; + return items; } @Override - public int getItemViewType(int arg0) { - return 0; - } + public View getView(int position, View convertView, ViewGroup parent) { + View view = super.getView(position, convertView, parent); + ButtonInfo info = getItem(position); + boolean enabled = isEnabled(position); - @Override - public View getView(int arg0, View convertView, ViewGroup parent) { - if(convertView == null) { - convertView = inflater.inflate(android.R.layout.select_dialog_item, parent,false); - } - TextView text = (TextView) convertView.findViewById(android.R.id.text1); - if (takenItems.contains(items.get(arg0))) { - text.setBackgroundColor(Color.parseColor("#181818")); - } else { - text.setBackground(null); - } - text.setText(mParent.getResources().getString(items.get(arg0).displayId)); - return convertView; - } + TextView text = (TextView) view.findViewById(R.id.key_text); + text.setText(getContext().getResources().getString(info.displayId)); + text.setEnabled(enabled); - @Override - public int getViewTypeCount() { - return 1; - } + ImageView icon = (ImageView) view.findViewById(R.id.key_icon); + icon.setImageResource(info.portResource); + icon.setColorFilter(new PorterDuffColorFilter( + text.getCurrentTextColor(), PorterDuff.Mode.SRC_IN)); - @Override - public boolean hasStableIds() { - return false; - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public void registerDataSetObserver(DataSetObserver arg0) { - } - - @Override - public void unregisterDataSetObserver(DataSetObserver arg0) { + return view; } @Override @@ -467,19 +435,8 @@ public class NavbarEditor implements OnTouchListener { } @Override - public boolean isEnabled(int arg0) { - if (takenItems.contains(items.get(arg0))) { - return false; - } - return true; + public boolean isEnabled(int position) { + return !mTakenItems.contains(getItem(position)); } - } - - final void dismissDialog() { - if (mDialog != null && mDialog.isShowing()) { - mDialog.dismiss(); - } - } - } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index 968cd38..e3f34a6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -32,6 +32,7 @@ import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Message; import android.os.ServiceManager; +import android.os.UserHandle; import android.util.AttributeSet; import android.util.Slog; import android.view.animation.AccelerateInterpolator; @@ -54,6 +55,7 @@ import com.android.systemui.statusbar.DelegateViewHelper; import com.android.systemui.statusbar.NavigationButtons; import com.android.systemui.statusbar.NavigationButtons.ButtonInfo; import com.android.systemui.statusbar.policy.DeadZone; +import com.android.systemui.statusbar.policy.KeyButtonView; public class NavigationBarView extends LinearLayout implements BaseStatusBar.NavigationBarCallback { final static boolean DEBUG = false; @@ -67,7 +69,7 @@ public class NavigationBarView extends LinearLayout implements BaseStatusBar.Nav final static boolean ANIMATE_HIDE_TRANSITION = false; // turned off because it introduces unsightly delay when videos goes to full screen final static String NAVBAR_EDIT = "android.intent.action.NAVBAR_EDIT"; - private static boolean EDIT_MODE; + private boolean mInEditMode; private NavbarEditor mEditBar; private NavBarReceiver mNavBarReceiver; private OnClickListener mRecentsClickListener; @@ -146,25 +148,38 @@ public class NavigationBarView extends LinearLayout implements BaseStatusBar.Nav private H mHandler = new H(); - public static boolean getEditMode() { - return EDIT_MODE; + public boolean isInEditMode() { + return mInEditMode; } - - protected void setListener(OnClickListener RecentsClickListener, OnTouchListener RecentsPreloadListener, OnTouchListener HomeSearchActionListener) { - mRecentsClickListener = RecentsClickListener; - mRecentsPreloadListener = RecentsPreloadListener; - mHomeSearchActionListener = HomeSearchActionListener; + + /* package */ void setListeners(OnClickListener recentsClickListener, + OnTouchListener recentsPreloadListener, OnTouchListener homeSearchActionListener) { + mRecentsClickListener = recentsClickListener; + mRecentsPreloadListener = recentsPreloadListener; + mHomeSearchActionListener = homeSearchActionListener; + } + + private void removeButtonListeners() { + ViewGroup container = (ViewGroup) mCurrentView.findViewById(R.id.container); + int viewCount = container.getChildCount(); + for (int i = 0; i < viewCount; i++) { + View button = container.getChildAt(i); + if (button instanceof KeyButtonView) { + button.setOnClickListener(null); + button.setOnTouchListener(null); + } + } } - protected void toggleButtonListener(boolean enable) { + protected void updateButtonListeners() { View recentView = mCurrentView.findViewWithTag(NavigationButtons.RECENT); if (recentView != null) { - recentView.setOnClickListener(enable ? mRecentsClickListener : null); - recentView.setOnTouchListener(enable ? mRecentsPreloadListener : null); + recentView.setOnClickListener(mRecentsClickListener); + recentView.setOnTouchListener(mRecentsPreloadListener); } View homeView = mCurrentView.findViewWithTag(NavigationButtons.HOME); if (homeView != null) { - homeView.setOnTouchListener(enable ? mHomeSearchActionListener : null); + homeView.setOnTouchListener(mHomeSearchActionListener); } } @@ -198,7 +213,8 @@ public class NavigationBarView extends LinearLayout implements BaseStatusBar.Nav updateResources(); mNavBarReceiver = new NavBarReceiver(); - mContext.registerReceiver(mNavBarReceiver, new IntentFilter(NAVBAR_EDIT)); + mContext.registerReceiverAsUser(mNavBarReceiver, UserHandle.ALL, + new IntentFilter(NAVBAR_EDIT), null, null); } protected void updateResources() { @@ -214,31 +230,29 @@ public class NavigationBarView extends LinearLayout implements BaseStatusBar.Nav public void onReceive(Context context, Intent intent) { boolean edit = intent.getBooleanExtra("edit", false); boolean save = intent.getBooleanExtra("save", false); - if (edit != EDIT_MODE) { - EDIT_MODE = edit; - if (EDIT_MODE) { - toggleButtonListener(false); - mEditBar.setupListeners(); - mEditBar.updateKeys(); + if (edit != mInEditMode) { + mInEditMode = edit; + if (edit) { + removeButtonListeners(); + mEditBar.setEditMode(true); } else { - mEditBar.dismissDialog(); if (save) { mEditBar.saveKeys(); } - mEditBar.reInflate(); - mEditBar = new NavbarEditor((ViewGroup) mCurrentView.findViewById(R.id.container), mVertical); - mEditBar.updateKeys(); - toggleButtonListener(true); - if (save) { - mEditBar.updateLowLights(mCurrentView); - } - ((ViewGroup) mCurrentView.findViewById(R.id.mid_nav_buttons)).setLayoutTransition( - new LayoutTransition()); + mEditBar.setEditMode(false); + updateSettings(); } } } } + public void updateSettings() { + mEditBar.updateKeys(); + removeButtonListeners(); + updateButtonListeners(); + setDisabledFlags(mDisabledFlags, true /* force */); + } + public void notifyScreenOn(boolean screenOn) { mScreenOn = screenOn; setDisabledFlags(mDisabledFlags, true); @@ -448,10 +462,8 @@ public class NavigationBarView extends LinearLayout implements BaseStatusBar.Nav } else { mVertical = getWidth() > 0 && getHeight() > getWidth(); } - mEditBar = new NavbarEditor((ViewGroup) mCurrentView.findViewById(R.id.container), mVertical); - mEditBar.updateKeys(); - mEditBar.updateLowLights(mCurrentView); - toggleButtonListener(true); + mEditBar = new NavbarEditor(mCurrentView, mVertical); + updateSettings(); mDeadZone = (DeadZone) mCurrentView.findViewById(R.id.deadzone); @@ -470,12 +482,16 @@ public class NavigationBarView extends LinearLayout implements BaseStatusBar.Nav @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); - ViewGroup mid_nav = (ViewGroup) mCurrentView.findViewById(R.id.mid_nav_buttons); - View vViews[] = new View[mid_nav.getChildCount()]; - for (int cc = 0;cc < mid_nav.getChildCount(); cc++) { - vViews[cc] = mid_nav.getChildAt(cc); + + ViewGroup midNavButtons = (ViewGroup) mCurrentView.findViewById(R.id.mid_nav_buttons); + int count = midNavButtons.getChildCount(); + View buttons[] = new View[count]; + + for (int i = 0; i < count; i++) { + buttons[i] = midNavButtons.getChildAt(i); } - mDelegateHelper.setInitialTouchRegion(vViews); + + mDelegateHelper.setInitialTouchRegion(buttons); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 02b98f4..7bc056a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -924,7 +924,8 @@ public class PhoneStatusBar extends BaseStatusBar { private void prepareNavigationBarView() { mNavigationBarView.reorient(); - mNavigationBarView.setListener(mRecentsClickListener,mRecentsPreloadOnTouchListener, mHomeSearchActionListener); + mNavigationBarView.setListeners(mRecentsClickListener, + mRecentsPreloadOnTouchListener, mHomeSearchActionListener); updateSearchPanel(); } @@ -2707,6 +2708,9 @@ public class PhoneStatusBar extends BaseStatusBar { if (mClock != null) { mClock.updateSettings(); } + if (mNavigationBarView != null) { + mNavigationBarView.updateSettings(); + } super.userSwitched(newUserId); } @@ -2927,7 +2931,8 @@ public class PhoneStatusBar extends BaseStatusBar { @Override protected boolean shouldDisableNavbarGestures() { return !isDeviceProvisioned() - || mExpandedVisible || NavigationBarView.getEditMode() + || mExpandedVisible + || (mNavigationBarView != null && mNavigationBarView.isInEditMode()) || (mDisabled & StatusBarManager.DISABLE_SEARCH) != 0; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java index 0bad729..5c4d9ac 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java @@ -38,11 +38,8 @@ import android.view.ViewConfiguration; import android.view.accessibility.AccessibilityEvent; import android.widget.ImageView; -import com.android.internal.util.ArrayUtils; import com.android.systemui.R; import com.android.systemui.statusbar.NavigationButtons; -import com.android.systemui.statusbar.phone.NavbarEditor; -import com.android.systemui.statusbar.phone.NavigationBarView; public class KeyButtonView extends ImageView { private static final String TAG = "StatusBar.KeyButtonView"; @@ -52,13 +49,15 @@ public class KeyButtonView extends ImageView { long mDownTime; int mCode; + boolean mIsSmall; int mTouchSlop; Drawable mGlowBG; int mGlowWidth, mGlowHeight; float mGlowAlpha = 0f, mGlowScale = 1f, mDrawingAlpha = 1f; - boolean mSupportsLongpress = true; + boolean mSupportsLongPress = true; RectF mRect = new RectF(0f,0f,0f,0f); AnimatorSet mPressedAnim; + boolean mInEditMode; Runnable mCheckLongPress = new Runnable() { public void run() { @@ -87,7 +86,7 @@ public class KeyButtonView extends ImageView { mCode = a.getInteger(R.styleable.KeyButtonView_keyCode, 0); - mSupportsLongpress = a.getBoolean(R.styleable.KeyButtonView_keyRepeat, true); + mSupportsLongPress = a.getBoolean(R.styleable.KeyButtonView_keyRepeat, true); mGlowBG = a.getDrawable(R.styleable.KeyButtonView_glowBackground); if (mGlowBG != null) { @@ -209,39 +208,57 @@ public class KeyButtonView extends ImageView { super.setPressed(pressed); } - public void setInfo(NavigationButtons.ButtonInfo buttonInfo, boolean isVertical) { - setTag(buttonInfo); + public void setEditMode(boolean editMode) { + mInEditMode = editMode; + updateVisibility(); + } + + public void setInfo(NavigationButtons.ButtonInfo buttonInfo, boolean isVertical, boolean isSmall) { final Resources res = getResources(); - setContentDescription(res.getString(buttonInfo.contentDescription)); + final int keyDrawableResId; + mCode = buttonInfo.keyCode; - boolean isSmallButton = ArrayUtils.contains(NavbarEditor.smallButtonIds, getId()); - Drawable keyD; - if (isSmallButton) { - keyD = res.getDrawable(buttonInfo.sideResource); + mIsSmall = isSmall; + + setTag(buttonInfo); + setContentDescription(res.getString(buttonInfo.contentDescription)); + + if (isSmall) { + keyDrawableResId = buttonInfo.sideResource; } else if (!isVertical) { - keyD = res.getDrawable(buttonInfo.portResource); + keyDrawableResId = buttonInfo.portResource; } else { - keyD = res.getDrawable(buttonInfo.landResource); + keyDrawableResId = buttonInfo.landResource; } + //Reason for setImageDrawable vs setImageResource is because setImageResource calls relayout() w/o //any checks. setImageDrawable performs size checks and only calls relayout if necessary. We rely on this //because otherwise the setX/setY attributes which are post layout cause it to mess up the layout. - setImageDrawable(keyD); + + setImageDrawable(res.getDrawable(keyDrawableResId)); + updateVisibility(); + } + + private void updateVisibility() { + if (mInEditMode) { + setVisibility(View.VISIBLE); + return; + } + + NavigationButtons.ButtonInfo buttonInfo = (NavigationButtons.ButtonInfo) getTag(); if (buttonInfo == NavigationButtons.EMPTY) { - if (isSmallButton) { - setVisibility(NavigationBarView.getEditMode() ? View.VISIBLE : View.INVISIBLE); - } else { - setVisibility(NavigationBarView.getEditMode() ? View.VISIBLE : View.GONE); - } + setVisibility(mIsSmall ? View.INVISIBLE : View.GONE); } else if (buttonInfo == NavigationButtons.CONDITIONAL_MENU) { - setVisibility(NavigationBarView.getEditMode() ? View.VISIBLE : View.INVISIBLE); - } else if (buttonInfo == NavigationButtons.HOME) { - mSupportsLongpress = false; + setVisibility(View.INVISIBLE); } } + private boolean supportsLongPress() { + return mSupportsLongPress && !NavigationButtons.HOME.equals(getTag()); + } + public boolean onTouchEvent(MotionEvent ev) { - if (NavigationBarView.getEditMode()) { + if (mInEditMode) { return false; } final int action = ev.getAction(); @@ -258,7 +275,7 @@ public class KeyButtonView extends ImageView { // Provide the same haptic feedback that the system offers for virtual keys. performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY); } - if (mSupportsLongpress) { + if (supportsLongPress()) { removeCallbacks(mCheckLongPress); postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout()); } @@ -276,7 +293,7 @@ public class KeyButtonView extends ImageView { if (mCode != 0) { sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED); } - if (mSupportsLongpress) { + if (supportsLongPress()) { removeCallbacks(mCheckLongPress); } break; @@ -297,7 +314,7 @@ public class KeyButtonView extends ImageView { performClick(); } } - if (mSupportsLongpress) { + if (supportsLongPress()) { removeCallbacks(mCheckLongPress); } break; -- cgit v1.1