2011-11-18 10:28:17 -08:00
|
|
|
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
2012-05-21 04:12:37 -07:00
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2011-11-18 10:28:17 -08:00
|
|
|
|
|
|
|
package org.mozilla.gecko;
|
|
|
|
|
2012-07-27 17:53:54 -07:00
|
|
|
import org.mozilla.gecko.gfx.LayerController;
|
|
|
|
|
|
|
|
import org.json.JSONArray;
|
|
|
|
import org.json.JSONObject;
|
|
|
|
|
2011-11-18 10:28:17 -08:00
|
|
|
import android.app.AlertDialog;
|
|
|
|
import android.content.Context;
|
|
|
|
import android.content.DialogInterface;
|
2012-01-24 16:31:33 -08:00
|
|
|
import android.content.DialogInterface.OnCancelListener;
|
2012-07-27 17:53:54 -07:00
|
|
|
import android.content.DialogInterface.OnClickListener;
|
2012-01-24 16:31:33 -08:00
|
|
|
import android.content.res.Resources;
|
2012-03-18 09:15:56 -07:00
|
|
|
import android.graphics.Bitmap;
|
|
|
|
import android.graphics.drawable.BitmapDrawable;
|
|
|
|
import android.graphics.drawable.Drawable;
|
2012-01-24 16:31:33 -08:00
|
|
|
import android.text.InputType;
|
2012-07-27 17:53:54 -07:00
|
|
|
import android.util.Log;
|
|
|
|
import android.view.LayoutInflater;
|
2011-11-18 10:28:17 -08:00
|
|
|
import android.view.View;
|
|
|
|
import android.view.ViewGroup;
|
|
|
|
import android.view.ViewGroup.LayoutParams;
|
|
|
|
import android.widget.AdapterView;
|
|
|
|
import android.widget.AdapterView.OnItemClickListener;
|
2012-07-27 17:53:54 -07:00
|
|
|
import android.widget.ArrayAdapter;
|
2011-11-18 10:28:17 -08:00
|
|
|
import android.widget.CheckBox;
|
|
|
|
import android.widget.CheckedTextView;
|
|
|
|
import android.widget.EditText;
|
|
|
|
import android.widget.LinearLayout;
|
|
|
|
import android.widget.ListView;
|
2012-07-27 17:53:54 -07:00
|
|
|
import android.widget.Spinner;
|
|
|
|
import android.widget.TextView;
|
|
|
|
|
|
|
|
import java.util.concurrent.SynchronousQueue;
|
|
|
|
import java.util.concurrent.TimeUnit;
|
2011-11-18 10:28:17 -08:00
|
|
|
|
2012-07-17 17:54:54 -07:00
|
|
|
public class PromptService implements OnClickListener, OnCancelListener, OnItemClickListener, GeckoEventResponder {
|
2011-11-18 10:28:17 -08:00
|
|
|
private static final String LOGTAG = "GeckoPromptService";
|
|
|
|
|
|
|
|
private PromptInput[] mInputs;
|
|
|
|
private AlertDialog mDialog = null;
|
2011-12-07 15:12:51 -08:00
|
|
|
private static LayoutInflater mInflater;
|
2012-03-18 09:15:56 -07:00
|
|
|
|
2012-07-27 23:13:34 -07:00
|
|
|
private int mGroupPaddingSize;
|
|
|
|
private int mLeftRightTextWithIconPadding;
|
|
|
|
private int mTopBottomTextWithIconPadding;
|
|
|
|
private int mIconTextPadding;
|
|
|
|
private int mIconSize;
|
2011-12-07 15:12:51 -08:00
|
|
|
|
|
|
|
PromptService() {
|
|
|
|
mInflater = LayoutInflater.from(GeckoApp.mAppContext);
|
2012-07-27 23:13:34 -07:00
|
|
|
|
2012-01-24 16:31:33 -08:00
|
|
|
Resources res = GeckoApp.mAppContext.getResources();
|
2012-07-27 23:13:34 -07:00
|
|
|
mGroupPaddingSize = (int) (res.getDimension(R.dimen.prompt_service_group_padding_size));
|
|
|
|
mLeftRightTextWithIconPadding = (int) (res.getDimension(R.dimen.prompt_service_left_right_text_with_icon_padding));
|
|
|
|
mTopBottomTextWithIconPadding = (int) (res.getDimension(R.dimen.prompt_service_top_bottom_text_with_icon_padding));
|
|
|
|
mIconTextPadding = (int) (res.getDimension(R.dimen.prompt_service_icon_text_padding));
|
|
|
|
mIconSize = (int) (res.getDimension(R.dimen.prompt_service_icon_size));
|
2012-06-13 14:12:15 -07:00
|
|
|
|
|
|
|
GeckoAppShell.registerGeckoEventListener("Prompt:Show", this);
|
2011-12-07 15:12:51 -08:00
|
|
|
}
|
2011-11-18 10:28:17 -08:00
|
|
|
|
2012-07-13 07:17:03 -07:00
|
|
|
void destroy() {
|
|
|
|
GeckoAppShell.unregisterGeckoEventListener("Prompt:Show", this);
|
|
|
|
}
|
|
|
|
|
2012-07-17 17:54:54 -07:00
|
|
|
private class PromptButton {
|
2011-11-18 10:28:17 -08:00
|
|
|
public String label = "";
|
|
|
|
PromptButton(JSONObject aJSONButton) {
|
|
|
|
try {
|
|
|
|
label = aJSONButton.getString("label");
|
|
|
|
} catch(Exception ex) { }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-17 17:54:54 -07:00
|
|
|
private class PromptInput {
|
2011-11-18 10:28:17 -08:00
|
|
|
private String label = "";
|
|
|
|
private String type = "";
|
|
|
|
private String hint = "";
|
|
|
|
private JSONObject mJSONInput = null;
|
|
|
|
private View view = null;
|
|
|
|
|
|
|
|
public PromptInput(JSONObject aJSONInput) {
|
|
|
|
mJSONInput = aJSONInput;
|
|
|
|
try {
|
|
|
|
label = aJSONInput.getString("label");
|
|
|
|
} catch(Exception ex) { }
|
|
|
|
try {
|
|
|
|
type = aJSONInput.getString("type");
|
|
|
|
} catch(Exception ex) { }
|
|
|
|
try {
|
|
|
|
hint = aJSONInput.getString("hint");
|
|
|
|
} catch(Exception ex) { }
|
|
|
|
}
|
|
|
|
|
|
|
|
public View getView() {
|
|
|
|
if (type.equals("checkbox")) {
|
|
|
|
CheckBox checkbox = new CheckBox(GeckoApp.mAppContext);
|
|
|
|
checkbox.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
|
|
|
|
checkbox.setText(label);
|
|
|
|
try {
|
|
|
|
Boolean value = mJSONInput.getBoolean("checked");
|
|
|
|
checkbox.setChecked(value);
|
|
|
|
} catch(Exception ex) { }
|
|
|
|
view = (View)checkbox;
|
|
|
|
} else if (type.equals("textbox") || this.type.equals("password")) {
|
|
|
|
EditText input = new EditText(GeckoApp.mAppContext);
|
|
|
|
int inputtype = InputType.TYPE_CLASS_TEXT;
|
|
|
|
if (type.equals("password")) {
|
|
|
|
inputtype |= InputType.TYPE_TEXT_VARIATION_PASSWORD | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
|
|
|
|
}
|
|
|
|
input.setInputType(inputtype);
|
|
|
|
|
|
|
|
try {
|
|
|
|
String value = mJSONInput.getString("value");
|
|
|
|
input.setText(value);
|
|
|
|
} catch(Exception ex) { }
|
|
|
|
|
|
|
|
if (!hint.equals("")) {
|
|
|
|
input.setHint(hint);
|
|
|
|
}
|
|
|
|
view = (View)input;
|
|
|
|
} else if (type.equals("menulist")) {
|
|
|
|
Spinner spinner = new Spinner(GeckoApp.mAppContext);
|
|
|
|
try {
|
|
|
|
String[] listitems = getStringArray(mJSONInput, "values");
|
|
|
|
if (listitems.length > 0) {
|
|
|
|
ArrayAdapter<String> adapter = new ArrayAdapter<String>(GeckoApp.mAppContext, android.R.layout.simple_dropdown_item_1line, listitems);
|
|
|
|
spinner.setAdapter(adapter);
|
|
|
|
}
|
|
|
|
} catch(Exception ex) { }
|
|
|
|
view = (View)spinner;
|
|
|
|
}
|
|
|
|
return view;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getName() {
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getValue() {
|
|
|
|
if (this.type.equals("checkbox")) {
|
|
|
|
CheckBox checkbox = (CheckBox)view;
|
|
|
|
return checkbox.isChecked() ? "true" : "false";
|
|
|
|
} else if (type.equals("textbox") || type.equals("password")) {
|
|
|
|
EditText edit = (EditText)view;
|
|
|
|
return edit.getText().toString();
|
|
|
|
} else if (type.equals("menulist")) {
|
|
|
|
Spinner spinner = (Spinner)view;
|
|
|
|
return Integer.toString(spinner.getSelectedItemPosition());
|
|
|
|
}
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-13 14:12:15 -07:00
|
|
|
// GeckoEventListener implementation
|
|
|
|
public void handleMessage(String event, final JSONObject message) {
|
|
|
|
GeckoAppShell.getHandler().post(new Runnable() {
|
|
|
|
public void run() {
|
|
|
|
processMessage(message);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// GeckoEventResponder implementation
|
|
|
|
public String getResponse() {
|
|
|
|
// we only handle one kind of message in handleMessage, and this is the
|
|
|
|
// response we provide for that message
|
|
|
|
String promptServiceResult = "";
|
|
|
|
try {
|
|
|
|
promptServiceResult = waitForReturn();
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
Log.i(LOGTAG, "showing prompt ", e);
|
|
|
|
}
|
|
|
|
return promptServiceResult;
|
|
|
|
}
|
|
|
|
|
2012-06-14 06:52:28 -07:00
|
|
|
public void show(String aTitle, String aText, PromptButton[] aButtons, PromptListItem[] aMenuList, boolean aMultipleSelection) {
|
Backout d2ee4c12c0b3 (bug 777351), 5aa6f94160dd (bug 777351), b47c470168fc (bug 777351), 5fb303ba52f7 (bug 777351), be81e4c3d928 (bug 777351), abc5b9a922dc (bug 777075), 8f1fc980f1f1 (bug 777075), 0b194a7f47d4 (bug 777075), d10df9bfef60 (bug 777075), 65393fe32cce (bug 777075), b52dc1df2fde (bug 777075), 8aeda525c094 (bug 777075) for Android native R1 failures on a CLOSED TREE
2012-08-01 10:42:05 -07:00
|
|
|
final LayerController controller = GeckoApp.mAppContext.getLayerController();
|
|
|
|
controller.post(new Runnable() {
|
2012-07-18 17:58:56 -07:00
|
|
|
public void run() {
|
|
|
|
// treat actions that show a dialog as if preventDefault by content to prevent panning
|
Backout d2ee4c12c0b3 (bug 777351), 5aa6f94160dd (bug 777351), b47c470168fc (bug 777351), 5fb303ba52f7 (bug 777351), be81e4c3d928 (bug 777351), abc5b9a922dc (bug 777075), 8f1fc980f1f1 (bug 777075), 0b194a7f47d4 (bug 777075), d10df9bfef60 (bug 777075), 65393fe32cce (bug 777075), b52dc1df2fde (bug 777075), 8aeda525c094 (bug 777075) for Android native R1 failures on a CLOSED TREE
2012-08-01 10:42:05 -07:00
|
|
|
controller.getPanZoomController().abortPanning();
|
2012-07-18 17:58:56 -07:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2011-11-18 10:28:17 -08:00
|
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(GeckoApp.mAppContext);
|
|
|
|
if (!aTitle.equals("")) {
|
|
|
|
builder.setTitle(aTitle);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!aText.equals("")) {
|
|
|
|
builder.setMessage(aText);
|
|
|
|
}
|
|
|
|
|
2012-03-18 09:15:56 -07:00
|
|
|
int length = mInputs == null ? 0 : mInputs.length;
|
|
|
|
if (aMenuList != null && aMenuList.length > 0) {
|
2011-11-18 10:28:17 -08:00
|
|
|
int resourceId = android.R.layout.select_dialog_item;
|
|
|
|
if (mSelected != null && mSelected.length > 0) {
|
|
|
|
if (aMultipleSelection) {
|
|
|
|
resourceId = android.R.layout.select_dialog_multichoice;
|
|
|
|
} else {
|
|
|
|
resourceId = android.R.layout.select_dialog_singlechoice;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
PromptListAdapter adapter = new PromptListAdapter(GeckoApp.mAppContext, resourceId, aMenuList);
|
|
|
|
if (mSelected != null && mSelected.length > 0) {
|
|
|
|
if (aMultipleSelection) {
|
2011-12-07 15:12:51 -08:00
|
|
|
adapter.listView = (ListView) mInflater.inflate(R.layout.select_dialog_list, null);
|
2011-11-18 10:28:17 -08:00
|
|
|
adapter.listView.setOnItemClickListener(this);
|
|
|
|
builder.setInverseBackgroundForced(true);
|
|
|
|
adapter.listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
|
|
|
|
adapter.listView.setAdapter(adapter);
|
|
|
|
builder.setView(adapter.listView);
|
|
|
|
} else {
|
|
|
|
int selectedIndex = -1;
|
|
|
|
for (int i = 0; i < mSelected.length; i++) {
|
|
|
|
if (mSelected[i]) {
|
|
|
|
selectedIndex = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mSelected = null;
|
|
|
|
builder.setSingleChoiceItems(adapter, selectedIndex, this);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
builder.setAdapter(adapter, this);
|
|
|
|
mSelected = null;
|
|
|
|
}
|
|
|
|
} else if (length == 1) {
|
|
|
|
builder.setView(mInputs[0].getView());
|
|
|
|
} else if (length > 1) {
|
|
|
|
LinearLayout linearLayout = new LinearLayout(GeckoApp.mAppContext);
|
|
|
|
linearLayout.setOrientation(LinearLayout.VERTICAL);
|
|
|
|
for (int i = 0; i < length; i++) {
|
|
|
|
View content = mInputs[i].getView();
|
|
|
|
linearLayout.addView(content);
|
|
|
|
}
|
|
|
|
builder.setView((View)linearLayout);
|
|
|
|
}
|
|
|
|
|
2012-03-18 09:15:56 -07:00
|
|
|
length = aButtons == null ? 0 : aButtons.length;
|
2011-11-18 10:28:17 -08:00
|
|
|
if (length > 0) {
|
|
|
|
builder.setPositiveButton(aButtons[0].label, this);
|
|
|
|
}
|
|
|
|
if (length > 1) {
|
|
|
|
builder.setNeutralButton(aButtons[1].label, this);
|
|
|
|
}
|
|
|
|
if (length > 2) {
|
|
|
|
builder.setNegativeButton(aButtons[2].label, this);
|
|
|
|
}
|
|
|
|
|
|
|
|
mDialog = builder.create();
|
|
|
|
mDialog.setOnCancelListener(this);
|
|
|
|
mDialog.show();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onClick(DialogInterface aDialog, int aWhich) {
|
|
|
|
JSONObject ret = new JSONObject();
|
|
|
|
try {
|
|
|
|
int button = -1;
|
|
|
|
ListView list = mDialog.getListView();
|
|
|
|
if (list != null || mSelected != null) {
|
|
|
|
button = aWhich;
|
|
|
|
if (mSelected != null) {
|
|
|
|
JSONArray selected = new JSONArray();
|
|
|
|
for (int i = 0; i < mSelected.length; i++) {
|
|
|
|
selected.put(mSelected[i]);
|
|
|
|
}
|
|
|
|
ret.put("button", selected);
|
|
|
|
} else {
|
|
|
|
ret.put("button", button);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
switch(aWhich) {
|
|
|
|
case DialogInterface.BUTTON_POSITIVE : button = 0; break;
|
|
|
|
case DialogInterface.BUTTON_NEUTRAL : button = 1; break;
|
|
|
|
case DialogInterface.BUTTON_NEGATIVE : button = 2; break;
|
|
|
|
}
|
|
|
|
ret.put("button", button);
|
|
|
|
}
|
|
|
|
if (mInputs != null) {
|
|
|
|
for (int i = 0; i < mInputs.length; i++) {
|
|
|
|
ret.put(mInputs[i].getName(), mInputs[i].getValue());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch(Exception ex) {
|
|
|
|
Log.i(LOGTAG, "Error building return: " + ex);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mDialog != null) {
|
|
|
|
mDialog.dismiss();
|
|
|
|
}
|
|
|
|
|
|
|
|
finishDialog(ret.toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean[] mSelected = null;
|
|
|
|
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
|
|
|
mSelected[position] = !mSelected[position];
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onCancel(DialogInterface aDialog) {
|
|
|
|
JSONObject ret = new JSONObject();
|
|
|
|
try {
|
|
|
|
ret.put("button", -1);
|
|
|
|
} catch(Exception ex) { }
|
|
|
|
finishDialog(ret.toString());
|
|
|
|
}
|
|
|
|
|
2012-03-18 09:15:56 -07:00
|
|
|
static SynchronousQueue<String> mPromptQueue = new SynchronousQueue<String>();
|
|
|
|
|
|
|
|
static public String waitForReturn() throws InterruptedException {
|
|
|
|
String value;
|
|
|
|
|
|
|
|
while (null == (value = mPromptQueue.poll(1, TimeUnit.MILLISECONDS))) {
|
|
|
|
GeckoAppShell.processNextNativeEvent();
|
|
|
|
}
|
|
|
|
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2011-11-18 10:28:17 -08:00
|
|
|
public void finishDialog(String aReturn) {
|
|
|
|
mInputs = null;
|
|
|
|
mDialog = null;
|
|
|
|
mSelected = null;
|
|
|
|
try {
|
2012-03-18 09:15:56 -07:00
|
|
|
mPromptQueue.put(aReturn);
|
2011-11-18 10:28:17 -08:00
|
|
|
} catch(Exception ex) { }
|
|
|
|
}
|
|
|
|
|
2012-06-13 14:12:15 -07:00
|
|
|
private void processMessage(JSONObject geckoObject) {
|
2011-11-18 10:28:17 -08:00
|
|
|
String title = "";
|
|
|
|
try {
|
|
|
|
title = geckoObject.getString("title");
|
|
|
|
} catch(Exception ex) { }
|
|
|
|
String text = "";
|
|
|
|
try {
|
|
|
|
text = geckoObject.getString("text");
|
|
|
|
} catch(Exception ex) { }
|
|
|
|
|
|
|
|
JSONArray buttons = new JSONArray();
|
|
|
|
try {
|
|
|
|
buttons = geckoObject.getJSONArray("buttons");
|
|
|
|
} catch(Exception ex) { }
|
|
|
|
int length = buttons.length();
|
|
|
|
PromptButton[] promptbuttons = new PromptButton[length];
|
|
|
|
for (int i = 0; i < length; i++) {
|
|
|
|
try {
|
|
|
|
promptbuttons[i] = new PromptButton(buttons.getJSONObject(i));
|
|
|
|
} catch(Exception ex) { }
|
|
|
|
}
|
|
|
|
|
|
|
|
JSONArray inputs = new JSONArray();
|
|
|
|
try {
|
|
|
|
inputs = geckoObject.getJSONArray("inputs");
|
|
|
|
} catch(Exception ex) { }
|
|
|
|
length = inputs.length();
|
|
|
|
mInputs = new PromptInput[length];
|
|
|
|
for (int i = 0; i < length; i++) {
|
|
|
|
try {
|
|
|
|
mInputs[i] = new PromptInput(inputs.getJSONObject(i));
|
|
|
|
} catch(Exception ex) { }
|
|
|
|
}
|
|
|
|
|
|
|
|
PromptListItem[] menuitems = getListItemArray(geckoObject, "listitems");
|
|
|
|
mSelected = getBooleanArray(geckoObject, "selected");
|
|
|
|
boolean multiple = false;
|
|
|
|
try {
|
|
|
|
multiple = geckoObject.getBoolean("multiple");
|
|
|
|
} catch(Exception ex) { }
|
2012-06-14 06:52:28 -07:00
|
|
|
show(title, text, promptbuttons, menuitems, multiple);
|
2011-11-18 10:28:17 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
private String[] getStringArray(JSONObject aObject, String aName) {
|
|
|
|
JSONArray items = new JSONArray();
|
|
|
|
try {
|
|
|
|
items = aObject.getJSONArray(aName);
|
|
|
|
} catch(Exception ex) { }
|
|
|
|
int length = items.length();
|
|
|
|
String[] list = new String[length];
|
|
|
|
for (int i = 0; i < length; i++) {
|
|
|
|
try {
|
|
|
|
list[i] = items.getString(i);
|
|
|
|
} catch(Exception ex) { }
|
|
|
|
}
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean[] getBooleanArray(JSONObject aObject, String aName) {
|
|
|
|
JSONArray items = new JSONArray();
|
|
|
|
try {
|
|
|
|
items = aObject.getJSONArray(aName);
|
|
|
|
} catch(Exception ex) { return null; }
|
|
|
|
int length = items.length();
|
|
|
|
boolean[] list = new boolean[length];
|
|
|
|
for (int i = 0; i < length; i++) {
|
|
|
|
try {
|
|
|
|
list[i] = items.getBoolean(i);
|
|
|
|
} catch(Exception ex) { }
|
|
|
|
}
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
private PromptListItem[] getListItemArray(JSONObject aObject, String aName) {
|
|
|
|
JSONArray items = new JSONArray();
|
|
|
|
try {
|
|
|
|
items = aObject.getJSONArray(aName);
|
|
|
|
} catch(Exception ex) { }
|
|
|
|
int length = items.length();
|
|
|
|
PromptListItem[] list = new PromptListItem[length];
|
|
|
|
for (int i = 0; i < length; i++) {
|
|
|
|
try {
|
|
|
|
list[i] = new PromptListItem(items.getJSONObject(i));
|
|
|
|
} catch(Exception ex) { }
|
|
|
|
}
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
2012-07-17 17:54:54 -07:00
|
|
|
static public class PromptListItem {
|
2011-11-18 10:28:17 -08:00
|
|
|
public String label = "";
|
|
|
|
public boolean isGroup = false;
|
|
|
|
public boolean inGroup = false;
|
|
|
|
public boolean disabled = false;
|
|
|
|
public int id = 0;
|
2012-03-18 09:15:56 -07:00
|
|
|
|
|
|
|
// This member can't be accessible from JS, see bug 733749.
|
|
|
|
public Drawable icon = null;
|
|
|
|
|
2011-11-18 10:28:17 -08:00
|
|
|
PromptListItem(JSONObject aObject) {
|
|
|
|
try { label = aObject.getString("label"); } catch(Exception ex) { }
|
|
|
|
try { isGroup = aObject.getBoolean("isGroup"); } catch(Exception ex) { }
|
|
|
|
try { inGroup = aObject.getBoolean("inGroup"); } catch(Exception ex) { }
|
|
|
|
try { disabled = aObject.getBoolean("disabled"); } catch(Exception ex) { }
|
|
|
|
try { id = aObject.getInt("id"); } catch(Exception ex) { }
|
|
|
|
}
|
2012-03-18 09:15:56 -07:00
|
|
|
|
|
|
|
public PromptListItem(String aLabel) {
|
|
|
|
label = aLabel;
|
|
|
|
}
|
2011-11-18 10:28:17 -08:00
|
|
|
}
|
|
|
|
|
2012-07-17 17:54:54 -07:00
|
|
|
public class PromptListAdapter extends ArrayAdapter<PromptListItem> {
|
2012-03-30 09:31:31 -07:00
|
|
|
private static final int VIEW_TYPE_ITEM = 0;
|
|
|
|
private static final int VIEW_TYPE_GROUP = 1;
|
|
|
|
private static final int VIEW_TYPE_COUNT = 2;
|
|
|
|
|
2011-11-18 10:28:17 -08:00
|
|
|
public ListView listView = null;
|
|
|
|
private int mResourceId = -1;
|
|
|
|
PromptListAdapter(Context context, int textViewResourceId, PromptListItem[] objects) {
|
|
|
|
super(context, textViewResourceId, objects);
|
|
|
|
mResourceId = textViewResourceId;
|
|
|
|
}
|
|
|
|
|
2012-03-30 09:31:31 -07:00
|
|
|
@Override
|
|
|
|
public int getItemViewType(int position) {
|
|
|
|
PromptListItem item = getItem(position);
|
|
|
|
return (item.isGroup ? VIEW_TYPE_GROUP : VIEW_TYPE_ITEM);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int getViewTypeCount() {
|
|
|
|
return VIEW_TYPE_COUNT;
|
|
|
|
}
|
|
|
|
|
2012-03-30 09:31:31 -07:00
|
|
|
private void maybeUpdateIcon(PromptListItem item, TextView t) {
|
|
|
|
if (item.icon == null)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Resources res = GeckoApp.mAppContext.getResources();
|
|
|
|
|
|
|
|
// Set padding inside the item.
|
|
|
|
t.setPadding(item.inGroup ? mLeftRightTextWithIconPadding + mGroupPaddingSize :
|
|
|
|
mLeftRightTextWithIconPadding,
|
|
|
|
mTopBottomTextWithIconPadding,
|
|
|
|
mLeftRightTextWithIconPadding,
|
|
|
|
mTopBottomTextWithIconPadding);
|
|
|
|
|
|
|
|
// Set the padding between the icon and the text.
|
|
|
|
t.setCompoundDrawablePadding(mIconTextPadding);
|
|
|
|
|
|
|
|
// We want the icon to be of a specific size. Some do not
|
|
|
|
// follow this rule so we have to resize them.
|
|
|
|
Bitmap bitmap = ((BitmapDrawable) item.icon).getBitmap();
|
|
|
|
Drawable d = new BitmapDrawable(Bitmap.createScaledBitmap(bitmap, mIconSize, mIconSize, true));
|
|
|
|
|
|
|
|
t.setCompoundDrawablesWithIntrinsicBounds(d, null, null, null);
|
|
|
|
}
|
|
|
|
|
2012-03-30 09:31:31 -07:00
|
|
|
private void maybeUpdateCheckedState(int position, PromptListItem item, ViewHolder viewHolder) {
|
2012-04-18 17:41:12 -07:00
|
|
|
if (item.isGroup || mSelected == null)
|
2012-03-30 09:31:31 -07:00
|
|
|
return;
|
|
|
|
|
|
|
|
CheckedTextView ct;
|
|
|
|
try {
|
|
|
|
ct = (CheckedTextView) viewHolder.textView;
|
|
|
|
} catch (Exception e) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ct.setEnabled(!item.disabled);
|
|
|
|
ct.setClickable(item.disabled);
|
|
|
|
|
|
|
|
// Apparently just using ct.setChecked(true) doesn't work, so this
|
|
|
|
// is stolen from the android source code as a way to set the checked
|
|
|
|
// state of these items
|
|
|
|
if (listView != null)
|
|
|
|
listView.setItemChecked(position, mSelected[position]);
|
|
|
|
|
|
|
|
ct.setPadding((item.inGroup ? mGroupPaddingSize : viewHolder.paddingLeft),
|
|
|
|
viewHolder.paddingTop,
|
|
|
|
viewHolder.paddingRight,
|
|
|
|
viewHolder.paddingBottom);
|
|
|
|
}
|
|
|
|
|
2012-07-26 18:17:23 -07:00
|
|
|
@Override
|
2011-11-18 10:28:17 -08:00
|
|
|
public View getView(int position, View convertView, ViewGroup parent) {
|
|
|
|
PromptListItem item = getItem(position);
|
2012-03-30 09:31:31 -07:00
|
|
|
ViewHolder viewHolder = null;
|
|
|
|
|
|
|
|
if (convertView == null) {
|
|
|
|
int resourceId = mResourceId;
|
|
|
|
if (item.isGroup) {
|
|
|
|
resourceId = R.layout.list_item_header;
|
|
|
|
}
|
|
|
|
|
|
|
|
convertView = mInflater.inflate(resourceId, null);
|
|
|
|
|
|
|
|
viewHolder = new ViewHolder();
|
|
|
|
viewHolder.textView = (TextView) convertView.findViewById(android.R.id.text1);
|
2012-03-30 09:31:31 -07:00
|
|
|
|
2012-03-30 09:31:31 -07:00
|
|
|
viewHolder.paddingLeft = viewHolder.textView.getPaddingLeft();
|
|
|
|
viewHolder.paddingRight = viewHolder.textView.getPaddingRight();
|
|
|
|
viewHolder.paddingTop = viewHolder.textView.getPaddingTop();
|
|
|
|
viewHolder.paddingBottom = viewHolder.textView.getPaddingBottom();
|
|
|
|
|
|
|
|
convertView.setTag(viewHolder);
|
|
|
|
} else {
|
|
|
|
viewHolder = (ViewHolder) convertView.getTag();
|
2011-11-18 10:28:17 -08:00
|
|
|
}
|
2012-03-30 09:31:31 -07:00
|
|
|
|
2012-03-30 09:31:31 -07:00
|
|
|
viewHolder.textView.setText(item.label);
|
2012-03-30 09:31:31 -07:00
|
|
|
maybeUpdateCheckedState(position, item, viewHolder);
|
2012-03-30 09:31:31 -07:00
|
|
|
maybeUpdateIcon(item, viewHolder.textView);
|
2011-11-18 10:28:17 -08:00
|
|
|
|
2012-03-30 09:31:31 -07:00
|
|
|
return convertView;
|
|
|
|
}
|
|
|
|
|
2012-07-17 17:54:54 -07:00
|
|
|
private class ViewHolder {
|
2012-03-30 09:31:31 -07:00
|
|
|
public TextView textView;
|
|
|
|
public int paddingLeft;
|
|
|
|
public int paddingRight;
|
|
|
|
public int paddingTop;
|
|
|
|
public int paddingBottom;
|
2011-11-18 10:28:17 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|