michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: package org.mozilla.gecko.preferences; michael@0: michael@0: import org.mozilla.gecko.animation.PropertyAnimator; michael@0: import org.mozilla.gecko.animation.PropertyAnimator.Property; michael@0: import org.mozilla.gecko.animation.ViewHelper; michael@0: import org.mozilla.gecko.R; michael@0: michael@0: import android.app.AlertDialog; michael@0: import android.app.Dialog; michael@0: import android.content.Context; michael@0: import android.content.DialogInterface; michael@0: import android.content.DialogInterface.OnClickListener; michael@0: import android.content.DialogInterface.OnShowListener; michael@0: import android.content.res.Resources; michael@0: import android.util.Log; michael@0: import android.view.View; michael@0: import android.view.ViewGroup; michael@0: import android.widget.TextView; michael@0: michael@0: public class PanelsPreference extends CustomListPreference { michael@0: protected String LOGTAG = "PanelsPreference"; michael@0: michael@0: // Position state of this Preference in enclosing category. michael@0: private static final int STATE_IS_FIRST = 0; michael@0: private static final int STATE_IS_LAST = 1; michael@0: michael@0: /** michael@0: * Index of the context menu button for controlling display options. michael@0: * For (removable) Dynamic panels, this button removes the panel. michael@0: * For built-in panels, this button toggles showing or hiding the panel. michael@0: */ michael@0: private static final int INDEX_DISPLAY_BUTTON = 1; michael@0: private static final int INDEX_REORDER_BUTTON = 2; michael@0: michael@0: // Indices of buttons in context menu for reordering. michael@0: private static final int INDEX_MOVE_UP_BUTTON = 0; michael@0: private static final int INDEX_MOVE_DOWN_BUTTON = 1; michael@0: michael@0: private String LABEL_HIDE; michael@0: private String LABEL_SHOW; michael@0: michael@0: private View preferenceView; michael@0: protected boolean mIsHidden = false; michael@0: private boolean mIsRemovable; michael@0: michael@0: private boolean mAnimate; michael@0: private static final int ANIMATION_DURATION_MS = 400; michael@0: michael@0: // State for reordering. michael@0: private int mPositionState = -1; michael@0: private final int mIndex; michael@0: michael@0: public PanelsPreference(Context context, CustomListCategory parentCategory, boolean isRemovable, int index, boolean animate) { michael@0: super(context, parentCategory); michael@0: mIsRemovable = isRemovable; michael@0: mIndex = index; michael@0: mAnimate = animate; michael@0: } michael@0: michael@0: @Override michael@0: protected int getPreferenceLayoutResource() { michael@0: return R.layout.preference_panels; michael@0: } michael@0: michael@0: @Override michael@0: protected void onBindView(View view) { michael@0: super.onBindView(view); michael@0: michael@0: // Override view handling so we can grey out "hidden" PanelPreferences. michael@0: view.setEnabled(!mIsHidden); michael@0: michael@0: if (view instanceof ViewGroup) { michael@0: final ViewGroup group = (ViewGroup) view; michael@0: for (int i = 0; i < group.getChildCount(); i++) { michael@0: group.getChildAt(i).setEnabled(!mIsHidden); michael@0: } michael@0: preferenceView = group; michael@0: } michael@0: michael@0: if (mAnimate) { michael@0: ViewHelper.setAlpha(preferenceView, 0); michael@0: michael@0: final PropertyAnimator animator = new PropertyAnimator(ANIMATION_DURATION_MS); michael@0: animator.attach(preferenceView, Property.ALPHA, 1); michael@0: animator.start(); michael@0: michael@0: // Clear animate flag. michael@0: mAnimate = false; michael@0: } michael@0: } michael@0: michael@0: @Override michael@0: protected String[] createDialogItems() { michael@0: final Resources res = getContext().getResources(); michael@0: final String labelReorder = res.getString(R.string.pref_panels_reorder); michael@0: michael@0: if (mIsRemovable) { michael@0: return new String[] { LABEL_SET_AS_DEFAULT, LABEL_REMOVE, labelReorder }; michael@0: } michael@0: michael@0: // Built-in panels can't be removed, so use show/hide options. michael@0: LABEL_HIDE = res.getString(R.string.pref_panels_hide); michael@0: LABEL_SHOW = res.getString(R.string.pref_panels_show); michael@0: michael@0: return new String[] { LABEL_SET_AS_DEFAULT, LABEL_HIDE, labelReorder }; michael@0: } michael@0: michael@0: @Override michael@0: public void setIsDefault(boolean isDefault) { michael@0: mIsDefault = isDefault; michael@0: if (isDefault) { michael@0: setSummary(LABEL_IS_DEFAULT); michael@0: if (mIsHidden) { michael@0: // Unhide the panel if it's being set as the default. michael@0: setHidden(false); michael@0: } michael@0: } else { michael@0: setSummary(""); michael@0: } michael@0: } michael@0: michael@0: @Override michael@0: protected void onDialogIndexClicked(int index) { michael@0: switch(index) { michael@0: case INDEX_SET_DEFAULT_BUTTON: michael@0: mParentCategory.setDefault(this); michael@0: break; michael@0: michael@0: case INDEX_DISPLAY_BUTTON: michael@0: // Handle display options for the panel. michael@0: if (mIsRemovable) { michael@0: // For removable panels, the button displays text for removing the panel. michael@0: mParentCategory.uninstall(this); michael@0: } else { michael@0: // Otherwise, the button toggles between text for showing or hiding the panel. michael@0: ((PanelsPreferenceCategory) mParentCategory).setHidden(this, !mIsHidden); michael@0: } michael@0: break; michael@0: michael@0: case INDEX_REORDER_BUTTON: michael@0: // Display dialog for changing preference order. michael@0: final Dialog orderDialog = makeReorderDialog(); michael@0: orderDialog.show(); michael@0: break; michael@0: michael@0: default: michael@0: Log.w(LOGTAG, "Selected index out of range: " + index); michael@0: } michael@0: } michael@0: michael@0: @Override michael@0: protected void configureShownDialog() { michael@0: super.configureShownDialog(); michael@0: michael@0: // Handle Show/Hide buttons. michael@0: if (!mIsRemovable) { michael@0: final TextView hideButton = (TextView) mDialog.getListView().getChildAt(INDEX_DISPLAY_BUTTON); michael@0: hideButton.setText(mIsHidden ? LABEL_SHOW : LABEL_HIDE); michael@0: } michael@0: } michael@0: michael@0: michael@0: private Dialog makeReorderDialog() { michael@0: final AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); michael@0: michael@0: final Resources res = getContext().getResources(); michael@0: final String labelUp = res.getString(R.string.pref_panels_move_up); michael@0: final String labelDown = res.getString(R.string.pref_panels_move_down); michael@0: michael@0: builder.setTitle(getTitle()); michael@0: builder.setItems(new String[] { labelUp, labelDown }, new OnClickListener() { michael@0: @Override michael@0: public void onClick(DialogInterface dialog, int index) { michael@0: dialog.dismiss(); michael@0: switch (index) { michael@0: case INDEX_MOVE_UP_BUTTON: michael@0: ((PanelsPreferenceCategory) mParentCategory).moveUp(PanelsPreference.this); michael@0: break; michael@0: michael@0: case INDEX_MOVE_DOWN_BUTTON: michael@0: ((PanelsPreferenceCategory) mParentCategory).moveDown(PanelsPreference.this); michael@0: break; michael@0: } michael@0: } michael@0: }); michael@0: michael@0: final Dialog dialog = builder.create(); michael@0: dialog.setOnShowListener(new OnShowListener() { michael@0: @Override michael@0: public void onShow(DialogInterface dialog) { michael@0: setReorderItemsEnabled(dialog); michael@0: } michael@0: }); michael@0: michael@0: return dialog; michael@0: } michael@0: michael@0: public void setIsFirst() { michael@0: mPositionState = STATE_IS_FIRST; michael@0: } michael@0: michael@0: public void setIsLast() { michael@0: mPositionState = STATE_IS_LAST; michael@0: } michael@0: michael@0: /** michael@0: * Configure enabled state of the reorder dialog, which must be done after the dialog is shown. michael@0: * @param dialog Dialog to configure michael@0: */ michael@0: private void setReorderItemsEnabled(DialogInterface dialog) { michael@0: // Update button enabled-ness for reordering. michael@0: switch (mPositionState) { michael@0: case STATE_IS_FIRST: michael@0: final TextView itemUp = (TextView) ((AlertDialog) dialog).getListView().getChildAt(INDEX_MOVE_UP_BUTTON); michael@0: itemUp.setEnabled(false); michael@0: // Disable clicks to this view. michael@0: itemUp.setOnClickListener(null); michael@0: break; michael@0: michael@0: case STATE_IS_LAST: michael@0: final TextView itemDown = (TextView) ((AlertDialog) dialog).getListView().getChildAt(INDEX_MOVE_DOWN_BUTTON); michael@0: itemDown.setEnabled(false); michael@0: // Disable clicks to this view. michael@0: itemDown.setOnClickListener(null); michael@0: break; michael@0: michael@0: default: michael@0: // Do nothing. michael@0: break; michael@0: } michael@0: } michael@0: michael@0: public void setHidden(boolean toHide) { michael@0: if (toHide) { michael@0: setIsDefault(false); michael@0: } michael@0: michael@0: if (mIsHidden != toHide) { michael@0: mIsHidden = toHide; michael@0: notifyChanged(); michael@0: } michael@0: } michael@0: michael@0: public boolean isHidden() { michael@0: return mIsHidden; michael@0: } michael@0: michael@0: public int getIndex() { michael@0: return mIndex; michael@0: } michael@0: }