SelectPopupDialog.java revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1// Copyright 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5package org.chromium.content.browser.input; 6 7import android.app.AlertDialog; 8import android.content.Context; 9import android.content.DialogInterface; 10import android.content.res.TypedArray; 11import android.util.SparseBooleanArray; 12import android.view.View; 13import android.widget.AdapterView; 14import android.widget.AdapterView.OnItemClickListener; 15import android.widget.ListView; 16 17import org.chromium.content.R; 18import org.chromium.content.browser.ContentViewCore; 19 20import java.util.List; 21 22/** 23 * Handles the popup dialog for the <select> HTML tag support. 24 */ 25public class SelectPopupDialog { 26 private static final int[] SELECT_DIALOG_ATTRS = { 27 R.attr.select_dialog_multichoice, 28 R.attr.select_dialog_singlechoice 29 }; 30 31 // The dialog hosting the popup list view. 32 private AlertDialog mListBoxPopup = null; 33 34 private final ContentViewCore mContentViewCore; 35 private final Context mContext; 36 37 private SelectPopupDialog(ContentViewCore contentViewCore, List<SelectPopupItem> items, 38 boolean multiple, int[] selected) { 39 mContentViewCore = contentViewCore; 40 mContext = mContentViewCore.getContext(); 41 42 final ListView listView = new ListView(mContext); 43 listView.setCacheColorHint(0); 44 AlertDialog.Builder b = new AlertDialog.Builder(mContext) 45 .setView(listView) 46 .setCancelable(true) 47 .setInverseBackgroundForced(true); 48 49 if (multiple) { 50 b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { 51 @Override 52 public void onClick(DialogInterface dialog, int which) { 53 mContentViewCore.selectPopupMenuItems(getSelectedIndices(listView)); 54 } 55 }); 56 b.setNegativeButton(android.R.string.cancel, 57 new DialogInterface.OnClickListener() { 58 @Override 59 public void onClick(DialogInterface dialog, int which) { 60 mContentViewCore.selectPopupMenuItems(null); 61 } 62 }); 63 } 64 mListBoxPopup = b.create(); 65 final SelectPopupAdapter adapter = new SelectPopupAdapter( 66 mContext, getSelectDialogLayout(multiple), items); 67 listView.setAdapter(adapter); 68 listView.setFocusableInTouchMode(true); 69 70 if (multiple) { 71 listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); 72 for (int i = 0; i < selected.length; ++i) { 73 listView.setItemChecked(selected[i], true); 74 } 75 } else { 76 listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 77 listView.setOnItemClickListener(new OnItemClickListener() { 78 @Override 79 public void onItemClick(AdapterView<?> parent, View v, 80 int position, long id) { 81 mContentViewCore.selectPopupMenuItems(getSelectedIndices(listView)); 82 mListBoxPopup.dismiss(); 83 } 84 }); 85 if (selected.length > 0) { 86 listView.setSelection(selected[0]); 87 listView.setItemChecked(selected[0], true); 88 } 89 } 90 mListBoxPopup.setOnCancelListener(new DialogInterface.OnCancelListener() { 91 @Override 92 public void onCancel(DialogInterface dialog) { 93 mContentViewCore.selectPopupMenuItems(null); 94 } 95 }); 96 } 97 98 private int getSelectDialogLayout(boolean isMultiChoice) { 99 int resourceId; 100 TypedArray styledAttributes = mContext.obtainStyledAttributes( 101 R.style.SelectPopupDialog, SELECT_DIALOG_ATTRS); 102 resourceId = styledAttributes.getResourceId(isMultiChoice ? 0 : 1, 0); 103 styledAttributes.recycle(); 104 return resourceId; 105 } 106 107 private int[] getSelectedIndices(ListView listView) { 108 SparseBooleanArray sparseArray = listView.getCheckedItemPositions(); 109 int selectedCount = 0; 110 for (int i = 0; i < sparseArray.size(); ++i) { 111 if (sparseArray.valueAt(i)) { 112 selectedCount++; 113 } 114 } 115 int[] indices = new int[selectedCount]; 116 for (int i = 0, j = 0; i < sparseArray.size(); ++i) { 117 if (sparseArray.valueAt(i)) { 118 indices[j++] = sparseArray.keyAt(i); 119 } 120 } 121 return indices; 122 } 123 124 /** 125 * Hides the select dialog. 126 */ 127 public void hide() { 128 mListBoxPopup.cancel(); 129 } 130 131 /** 132 * Shows the popup menu triggered by the passed ContentView. 133 * Hides any currently shown popup. 134 * @param items Items to show. 135 * @param multiple Whether the popup menu should support multi-select. 136 * @param selectedIndices Indices of selected items. 137 * @return The select dialog created. 138 */ 139 public static SelectPopupDialog show( 140 ContentViewCore contentViewCore, List<SelectPopupItem> items, 141 boolean multiple, int[] selectedIndices) { 142 SelectPopupDialog dialog = new SelectPopupDialog( 143 contentViewCore, items, multiple, selectedIndices); 144 dialog.mListBoxPopup.show(); 145 return dialog; 146 } 147} 148