1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/base/preferences/PanelsPreference.java Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,255 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +package org.mozilla.gecko.preferences; 1.9 + 1.10 +import org.mozilla.gecko.animation.PropertyAnimator; 1.11 +import org.mozilla.gecko.animation.PropertyAnimator.Property; 1.12 +import org.mozilla.gecko.animation.ViewHelper; 1.13 +import org.mozilla.gecko.R; 1.14 + 1.15 +import android.app.AlertDialog; 1.16 +import android.app.Dialog; 1.17 +import android.content.Context; 1.18 +import android.content.DialogInterface; 1.19 +import android.content.DialogInterface.OnClickListener; 1.20 +import android.content.DialogInterface.OnShowListener; 1.21 +import android.content.res.Resources; 1.22 +import android.util.Log; 1.23 +import android.view.View; 1.24 +import android.view.ViewGroup; 1.25 +import android.widget.TextView; 1.26 + 1.27 +public class PanelsPreference extends CustomListPreference { 1.28 + protected String LOGTAG = "PanelsPreference"; 1.29 + 1.30 + // Position state of this Preference in enclosing category. 1.31 + private static final int STATE_IS_FIRST = 0; 1.32 + private static final int STATE_IS_LAST = 1; 1.33 + 1.34 + /** 1.35 + * Index of the context menu button for controlling display options. 1.36 + * For (removable) Dynamic panels, this button removes the panel. 1.37 + * For built-in panels, this button toggles showing or hiding the panel. 1.38 + */ 1.39 + private static final int INDEX_DISPLAY_BUTTON = 1; 1.40 + private static final int INDEX_REORDER_BUTTON = 2; 1.41 + 1.42 + // Indices of buttons in context menu for reordering. 1.43 + private static final int INDEX_MOVE_UP_BUTTON = 0; 1.44 + private static final int INDEX_MOVE_DOWN_BUTTON = 1; 1.45 + 1.46 + private String LABEL_HIDE; 1.47 + private String LABEL_SHOW; 1.48 + 1.49 + private View preferenceView; 1.50 + protected boolean mIsHidden = false; 1.51 + private boolean mIsRemovable; 1.52 + 1.53 + private boolean mAnimate; 1.54 + private static final int ANIMATION_DURATION_MS = 400; 1.55 + 1.56 + // State for reordering. 1.57 + private int mPositionState = -1; 1.58 + private final int mIndex; 1.59 + 1.60 + public PanelsPreference(Context context, CustomListCategory parentCategory, boolean isRemovable, int index, boolean animate) { 1.61 + super(context, parentCategory); 1.62 + mIsRemovable = isRemovable; 1.63 + mIndex = index; 1.64 + mAnimate = animate; 1.65 + } 1.66 + 1.67 + @Override 1.68 + protected int getPreferenceLayoutResource() { 1.69 + return R.layout.preference_panels; 1.70 + } 1.71 + 1.72 + @Override 1.73 + protected void onBindView(View view) { 1.74 + super.onBindView(view); 1.75 + 1.76 + // Override view handling so we can grey out "hidden" PanelPreferences. 1.77 + view.setEnabled(!mIsHidden); 1.78 + 1.79 + if (view instanceof ViewGroup) { 1.80 + final ViewGroup group = (ViewGroup) view; 1.81 + for (int i = 0; i < group.getChildCount(); i++) { 1.82 + group.getChildAt(i).setEnabled(!mIsHidden); 1.83 + } 1.84 + preferenceView = group; 1.85 + } 1.86 + 1.87 + if (mAnimate) { 1.88 + ViewHelper.setAlpha(preferenceView, 0); 1.89 + 1.90 + final PropertyAnimator animator = new PropertyAnimator(ANIMATION_DURATION_MS); 1.91 + animator.attach(preferenceView, Property.ALPHA, 1); 1.92 + animator.start(); 1.93 + 1.94 + // Clear animate flag. 1.95 + mAnimate = false; 1.96 + } 1.97 + } 1.98 + 1.99 + @Override 1.100 + protected String[] createDialogItems() { 1.101 + final Resources res = getContext().getResources(); 1.102 + final String labelReorder = res.getString(R.string.pref_panels_reorder); 1.103 + 1.104 + if (mIsRemovable) { 1.105 + return new String[] { LABEL_SET_AS_DEFAULT, LABEL_REMOVE, labelReorder }; 1.106 + } 1.107 + 1.108 + // Built-in panels can't be removed, so use show/hide options. 1.109 + LABEL_HIDE = res.getString(R.string.pref_panels_hide); 1.110 + LABEL_SHOW = res.getString(R.string.pref_panels_show); 1.111 + 1.112 + return new String[] { LABEL_SET_AS_DEFAULT, LABEL_HIDE, labelReorder }; 1.113 + } 1.114 + 1.115 + @Override 1.116 + public void setIsDefault(boolean isDefault) { 1.117 + mIsDefault = isDefault; 1.118 + if (isDefault) { 1.119 + setSummary(LABEL_IS_DEFAULT); 1.120 + if (mIsHidden) { 1.121 + // Unhide the panel if it's being set as the default. 1.122 + setHidden(false); 1.123 + } 1.124 + } else { 1.125 + setSummary(""); 1.126 + } 1.127 + } 1.128 + 1.129 + @Override 1.130 + protected void onDialogIndexClicked(int index) { 1.131 + switch(index) { 1.132 + case INDEX_SET_DEFAULT_BUTTON: 1.133 + mParentCategory.setDefault(this); 1.134 + break; 1.135 + 1.136 + case INDEX_DISPLAY_BUTTON: 1.137 + // Handle display options for the panel. 1.138 + if (mIsRemovable) { 1.139 + // For removable panels, the button displays text for removing the panel. 1.140 + mParentCategory.uninstall(this); 1.141 + } else { 1.142 + // Otherwise, the button toggles between text for showing or hiding the panel. 1.143 + ((PanelsPreferenceCategory) mParentCategory).setHidden(this, !mIsHidden); 1.144 + } 1.145 + break; 1.146 + 1.147 + case INDEX_REORDER_BUTTON: 1.148 + // Display dialog for changing preference order. 1.149 + final Dialog orderDialog = makeReorderDialog(); 1.150 + orderDialog.show(); 1.151 + break; 1.152 + 1.153 + default: 1.154 + Log.w(LOGTAG, "Selected index out of range: " + index); 1.155 + } 1.156 + } 1.157 + 1.158 + @Override 1.159 + protected void configureShownDialog() { 1.160 + super.configureShownDialog(); 1.161 + 1.162 + // Handle Show/Hide buttons. 1.163 + if (!mIsRemovable) { 1.164 + final TextView hideButton = (TextView) mDialog.getListView().getChildAt(INDEX_DISPLAY_BUTTON); 1.165 + hideButton.setText(mIsHidden ? LABEL_SHOW : LABEL_HIDE); 1.166 + } 1.167 + } 1.168 + 1.169 + 1.170 + private Dialog makeReorderDialog() { 1.171 + final AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); 1.172 + 1.173 + final Resources res = getContext().getResources(); 1.174 + final String labelUp = res.getString(R.string.pref_panels_move_up); 1.175 + final String labelDown = res.getString(R.string.pref_panels_move_down); 1.176 + 1.177 + builder.setTitle(getTitle()); 1.178 + builder.setItems(new String[] { labelUp, labelDown }, new OnClickListener() { 1.179 + @Override 1.180 + public void onClick(DialogInterface dialog, int index) { 1.181 + dialog.dismiss(); 1.182 + switch (index) { 1.183 + case INDEX_MOVE_UP_BUTTON: 1.184 + ((PanelsPreferenceCategory) mParentCategory).moveUp(PanelsPreference.this); 1.185 + break; 1.186 + 1.187 + case INDEX_MOVE_DOWN_BUTTON: 1.188 + ((PanelsPreferenceCategory) mParentCategory).moveDown(PanelsPreference.this); 1.189 + break; 1.190 + } 1.191 + } 1.192 + }); 1.193 + 1.194 + final Dialog dialog = builder.create(); 1.195 + dialog.setOnShowListener(new OnShowListener() { 1.196 + @Override 1.197 + public void onShow(DialogInterface dialog) { 1.198 + setReorderItemsEnabled(dialog); 1.199 + } 1.200 + }); 1.201 + 1.202 + return dialog; 1.203 + } 1.204 + 1.205 + public void setIsFirst() { 1.206 + mPositionState = STATE_IS_FIRST; 1.207 + } 1.208 + 1.209 + public void setIsLast() { 1.210 + mPositionState = STATE_IS_LAST; 1.211 + } 1.212 + 1.213 + /** 1.214 + * Configure enabled state of the reorder dialog, which must be done after the dialog is shown. 1.215 + * @param dialog Dialog to configure 1.216 + */ 1.217 + private void setReorderItemsEnabled(DialogInterface dialog) { 1.218 + // Update button enabled-ness for reordering. 1.219 + switch (mPositionState) { 1.220 + case STATE_IS_FIRST: 1.221 + final TextView itemUp = (TextView) ((AlertDialog) dialog).getListView().getChildAt(INDEX_MOVE_UP_BUTTON); 1.222 + itemUp.setEnabled(false); 1.223 + // Disable clicks to this view. 1.224 + itemUp.setOnClickListener(null); 1.225 + break; 1.226 + 1.227 + case STATE_IS_LAST: 1.228 + final TextView itemDown = (TextView) ((AlertDialog) dialog).getListView().getChildAt(INDEX_MOVE_DOWN_BUTTON); 1.229 + itemDown.setEnabled(false); 1.230 + // Disable clicks to this view. 1.231 + itemDown.setOnClickListener(null); 1.232 + break; 1.233 + 1.234 + default: 1.235 + // Do nothing. 1.236 + break; 1.237 + } 1.238 + } 1.239 + 1.240 + public void setHidden(boolean toHide) { 1.241 + if (toHide) { 1.242 + setIsDefault(false); 1.243 + } 1.244 + 1.245 + if (mIsHidden != toHide) { 1.246 + mIsHidden = toHide; 1.247 + notifyChanged(); 1.248 + } 1.249 + } 1.250 + 1.251 + public boolean isHidden() { 1.252 + return mIsHidden; 1.253 + } 1.254 + 1.255 + public int getIndex() { 1.256 + return mIndex; 1.257 + } 1.258 +}