Bug 959742 - Auto close lists if they don't have any buttons on them. r=bnicholson
☠☠ backed out by 977b4d18c0e9 ☠ ☠
authorWesley Johnston <wjohnston>
Thu, 06 Feb 2014 16:26:00 -0800
changeset 171213 b0fd368ba5ece7072ec29ff24336e26a8ca323cf
parent 171212 4e909fc8094379b4f56b8b7c93fa29e61d1a1dfe
child 171214 ec51bb26527af7c988a235856c8bf6ecae2b0074
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersbnicholson
bugs959742
milestone30.0a1
Bug 959742 - Auto close lists if they don't have any buttons on them. r=bnicholson
mobile/android/base/prompts/IconGridInput.java
mobile/android/base/prompts/Prompt.java
mobile/android/base/prompts/PromptInput.java
mobile/android/base/prompts/TabInput.java
--- a/mobile/android/base/prompts/IconGridInput.java
+++ b/mobile/android/base/prompts/IconGridInput.java
@@ -87,16 +87,17 @@ public class IconGridInput extends Promp
         view.setAdapter(mAdapter);
         mView = view;
         return mView;
     }
 
     @Override
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
         mSelected = position;
+        notifyListeners(Integer.toString(position));
     }
 
     @Override
     public Object getValue() {
         return new Integer(mSelected);
     }
 
     @Override
--- a/mobile/android/base/prompts/Prompt.java
+++ b/mobile/android/base/prompts/Prompt.java
@@ -198,33 +198,17 @@ public class Prompt implements OnClickLi
         try {
             result.put("button", button);
         } catch(JSONException ex) { }
     }
 
     @Override
     public void onClick(DialogInterface dialog, int which) {
         ThreadUtils.assertOnUiThread();
-        JSONObject ret = new JSONObject();
-        try {
-            addButtonResult(ret, which);
-            addInputValues(ret);
-
-            if (mAdapter != null) {
-                addListResult(ret, which);
-            }
-        } catch(Exception ex) {
-            Log.i(LOGTAG, "Error building return: " + ex);
-        }
-
-        if (dialog != null) {
-            dialog.dismiss();
-        }
-
-        finishDialog(ret);
+        closeIfNoButtons(which);
     }
 
     /* Adds a set of list items to the prompt. This can be used for either context menu type dialogs, checked lists,
      * or multiple selection lists.
      *
      * @param builder
      *        The alert builder currently building this dialog.
      * @param listItems
@@ -355,16 +339,29 @@ public class Prompt implements OnClickLi
 
     /* AdapterView.OnItemClickListener
      * Called when a list item is clicked
      */
     @Override
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
         ThreadUtils.assertOnUiThread();
         mAdapter.toggleSelected(position);
+
+        // If there are no buttons on this dialog, then we take selecting an item as a sign to close
+        // the dialog. Note that means it will be hard to select multiple things in this list, but
+        // given there is no way to confirm+close the dialog, it seems reasonable.
+        closeIfNoButtons(position);
+    }
+
+    private boolean closeIfNoButtons(int selected) {
+        if (mButtons == null || mButtons.length == 0) {
+            closeDialog(selected);
+            return true;
+        }
+        return false;
     }
 
     /* @DialogInterface.OnCancelListener
      * Called when the user hits back to cancel a dialog. The dialog will close itself when this
      * ends. Setup the correct return values here.
      *
      * @param aDialog
      *          A dialog interface for the dialog that's being closed.
@@ -385,16 +382,30 @@ public class Prompt implements OnClickLi
         } catch(Exception ex) { }
         addInputValues(ret);
         finishDialog(ret);
     }
 
     /* Called any time we're closing the dialog to cleanup and notify listeners that the dialog
      * is closing.
      */
+    public void closeDialog(int which) {
+        JSONObject ret = new JSONObject();
+        mDialog.dismiss();
+
+        addButtonResult(ret, which);
+        addListResult(ret, which);
+        addInputValues(ret);
+
+        finishDialog(ret);
+    }
+
+    /* Called any time we're closing the dialog to cleanup and notify listeners that the dialog
+     * is closing.
+     */
     public void finishDialog(JSONObject aReturn) {
         mInputs = null;
         mButtons = null;
         mDialog = null;
         try {
             aReturn.put("guid", mGuid);
         } catch(JSONException ex) { }
 
@@ -416,32 +427,41 @@ public class Prompt implements OnClickLi
 
         mButtons = getStringArray(geckoObject, "buttons");
 
         JSONArray inputs = getSafeArray(geckoObject, "inputs");
         mInputs = new PromptInput[inputs.length()];
         for (int i = 0; i < mInputs.length; i++) {
             try {
                 mInputs[i] = PromptInput.getInput(inputs.getJSONObject(i));
+                mInputs[i].setListener(this);
             } catch(Exception ex) { }
         }
 
         PromptListItem[] menuitems = PromptListItem.getArray(geckoObject.optJSONArray("listitems"));
         String selected = geckoObject.optString("choiceMode");
 
         int choiceMode = ListView.CHOICE_MODE_NONE;
         if ("single".equals(selected)) {
             choiceMode = ListView.CHOICE_MODE_SINGLE;
         } else if ("multiple".equals(selected)) {
             choiceMode = ListView.CHOICE_MODE_MULTIPLE;
         }
 
         show(title, text, menuitems, choiceMode);
     }
 
+    // Called when the prompt inputs on the dialog change
+    public void onChange(PromptInput input) {
+        // If there are no buttons on this dialog, assuming that "changing" an input
+        // means something was selected and we can close. This provides a way to tap
+        // on a list item and close the dialog automatically.
+        closeIfNoButtons(-1);
+    }
+
     private static JSONArray getSafeArray(JSONObject json, String key) {
         try {
             return json.getJSONArray(key);
         } catch (Exception e) {
             return new JSONArray();
         }
     }
 
--- a/mobile/android/base/prompts/PromptInput.java
+++ b/mobile/android/base/prompts/PromptInput.java
@@ -33,19 +33,28 @@ import android.widget.Spinner;
 import android.widget.TextView;
 import android.widget.TimePicker;
 
 public class PromptInput {
     protected final String mLabel;
     protected final String mType;
     protected final String mId;
     protected final String mValue;
+    protected OnChangeListener mListener;
     protected View mView;
     public static final String LOGTAG = "GeckoPromptInput";
 
+    public interface OnChangeListener {
+        public void onChange(PromptInput input);
+    }
+
+    public void setListener(OnChangeListener listener) {
+        mListener = listener;
+    }
+
     public static class EditInput extends PromptInput {
         protected final String mHint;
         protected final boolean mAutofocus;
         public static final String INPUT_TYPE = "textbox";
 
         public EditInput(JSONObject object) {
             super(object);
             mHint = object.optString("hint");
@@ -371,9 +380,15 @@ public class PromptInput {
 
     public boolean getScrollable() {
         return false;
     }
 
     public boolean canApplyInputStyle() {
         return true;
     }
+
+    protected void notifyListeners(String val) {
+        if (mListener != null) {
+            mListener.onChange(this);
+        }
+    }
 }
--- a/mobile/android/base/prompts/TabInput.java
+++ b/mobile/android/base/prompts/TabInput.java
@@ -99,11 +99,12 @@ public class TabInput extends PromptInpu
     public boolean canApplyInputStyle() {
         return false;
     }
 
     @Override
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
         ThreadUtils.assertOnUiThread();
         mPosition = position;
+        notifyListeners(Integer.toString(position));
     }
 
 }