Bug 737922: Invert form validation arrow if it is shown on top. [r=mfinkle] [a=blocking-fennec]
authorSriram Ramasubramanian <sriram@mozilla.com>
Wed, 18 Apr 2012 15:35:36 -0700
changeset 95297 8b1087512ec4787852ab2625eb46d047f4e5c510
parent 95296 d585de9a3103dbdcca84b08e07d88049f381d182
child 95298 d91d3787a3efc06c533b1f42e76aae9c7781e0cb
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle, blocking-fennec
bugs737922
milestone14.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 737922: Invert form validation arrow if it is shown on top. [r=mfinkle] [a=blocking-fennec]
mobile/android/base/FormAssistPopup.java
mobile/android/base/Makefile.in
mobile/android/base/resources/drawable-hdpi/validation_arrow_inverted.png
mobile/android/base/resources/drawable-xhdpi-v11/validation_arrow_inverted.png
mobile/android/base/resources/drawable/validation_arrow_inverted.png
mobile/android/base/resources/layout/validation_message.xml
--- a/mobile/android/base/FormAssistPopup.java
+++ b/mobile/android/base/FormAssistPopup.java
@@ -49,45 +49,53 @@ import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.ArrayAdapter;
 import android.widget.AdapterView;
+import android.widget.ImageView;
+import android.widget.ListView;
 import android.widget.RelativeLayout;
-import android.widget.ListView;
 import android.widget.TextView;
 
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
 public class FormAssistPopup extends RelativeLayout implements GeckoEventListener {
     private Context mContext;
     private Animation mAnimation; 
 
     private ListView mAutoCompleteList;
     private RelativeLayout mValidationMessage;
     private TextView mValidationMessageText;
+    private ImageView mValidationMessageArrow;
+    private ImageView mValidationMessageArrowInverted;
 
     private static int sAutoCompleteMinWidth = 0;
     private static int sAutoCompleteRowHeight = 0;
     private static int sValidationMessageHeight = 0;
+    private static int sValidationTextMarginTop = 0;
+    private static RelativeLayout.LayoutParams sValidationTextLayoutNormal;
+    private static RelativeLayout.LayoutParams sValidationTextLayoutInverted;
 
     // Minimum popup width for autocomplete messages
     private static final int AUTOCOMPLETE_MIN_WIDTH_IN_DPI = 200;
 
     // Height of the autocomplete_list_item TextView
     private static final int AUTOCOMPLETE_ROW_HEIGHT_IN_DPI = 32;
 
-    // Height of the validation_message_text TextView, plus the top margin set to
-    // make room for the arrow
-    private static final int VALIDATION_MESSAGE_HEIGHT_IN_DPI = 58;
+    // Height of the validation_message_text TextView
+    private static final int VALIDATION_MESSAGE_HEIGHT_IN_DPI = 50;
+
+    // Top margin for the validation_message_text TextView
+    private static final int VALIDATION_MESSAGE_MARGIN_TOP_IN_DPI = 6;
 
     private static final String LOGTAG = "FormAssistPopup";
 
     public FormAssistPopup(Context context, AttributeSet attrs) {
         super(context, attrs);
         mContext = context;
 
         mAnimation = AnimationUtils.loadAnimation(context, R.anim.grow_fade_in);
@@ -172,16 +180,29 @@ public class FormAssistPopup extends Rel
 
     private void showValidationMessage(String validationMessage, JSONArray rect, double zoom) {
         if (mValidationMessage == null) {
             LayoutInflater inflater = LayoutInflater.from(mContext);
             mValidationMessage = (RelativeLayout) inflater.inflate(R.layout.validation_message, null);
 
             addView(mValidationMessage);
             mValidationMessageText = (TextView) mValidationMessage.findViewById(R.id.validation_message_text);
+
+            DisplayMetrics metrics = new DisplayMetrics();
+            GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics);
+            sValidationTextMarginTop = (int) (VALIDATION_MESSAGE_MARGIN_TOP_IN_DPI * metrics.density);
+
+            sValidationTextLayoutNormal = new RelativeLayout.LayoutParams(mValidationMessageText.getLayoutParams());
+            sValidationTextLayoutNormal.setMargins(0, sValidationTextMarginTop, 0, 0);
+
+            sValidationTextLayoutInverted = new RelativeLayout.LayoutParams(sValidationTextLayoutNormal);
+            sValidationTextLayoutInverted.setMargins(0, 0, 0, 0);
+
+            mValidationMessageArrow = (ImageView) mValidationMessage.findViewById(R.id.validation_message_arrow);
+            mValidationMessageArrowInverted = (ImageView) mValidationMessage.findViewById(R.id.validation_message_arrow_inverted);
         }
 
         mValidationMessageText.setText(validationMessage);
 
         // We need to set the text as selected for the marquee text to work.
         mValidationMessageText.setSelected(true);
 
         positionAndShowPopup(rect, zoom, false);
@@ -253,32 +274,44 @@ public class FormAssistPopup extends Rel
         int popupHeight;
         if (isAutoComplete)
             popupHeight = sAutoCompleteRowHeight * mAutoCompleteList.getAdapter().getCount();
         else
             popupHeight = sValidationMessageHeight;
 
         int popupTop = top + height;
 
+        if (!isAutoComplete) {
+            mValidationMessageText.setLayoutParams(sValidationTextLayoutNormal);
+            mValidationMessageArrow.setVisibility(VISIBLE);
+            mValidationMessageArrowInverted.setVisibility(GONE);
+        }
+
         // If the popup doesn't fit below the input box, shrink its height, or
         // see if we can place it above the input instead.
         if ((popupTop + popupHeight) > viewport.height) {
             // Find where the maximum space is, and put the popup there.
             if ((viewport.height - popupTop) > top) {
                 // Shrink the height to fit it below the input box.
                 popupHeight = (int) (viewport.height - popupTop);
             } else {
                 if (popupHeight < top) {
                     // No shrinking needed to fit on top.
                     popupTop = (top - popupHeight);
                 } else {
                     // Shrink to available space on top.
                     popupTop = 0;
                     popupHeight = top;
                 }
+
+                if (!isAutoComplete) {
+                    mValidationMessageText.setLayoutParams(sValidationTextLayoutInverted);
+                    mValidationMessageArrow.setVisibility(GONE);
+                    mValidationMessageArrowInverted.setVisibility(VISIBLE);
+                }
            }
         }
 
         RelativeLayout.LayoutParams layoutParams =
                 new RelativeLayout.LayoutParams(popupWidth, popupHeight);
         layoutParams.setMargins(popupLeft, popupTop, 0, 0);
         setLayoutParams(layoutParams);
         requestLayout();
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -361,16 +361,17 @@ RES_DRAWABLE_BASE = \
   res/drawable/doorhanger_arrow.png \
   res/drawable/doorhanger_bg.9.png \
   res/drawable/doorhanger_shadow_bg.9.png \
   res/drawable/doorhanger_popup_bg.9.png \
   res/drawable/site_security_identified.png \
   res/drawable/site_security_verified.png \
   res/drawable/urlbar_stop.png \
   res/drawable/validation_arrow.png \
+  res/drawable/validation_arrow_inverted.png \
   res/drawable/validation_bg.9.png \
   res/drawable/bookmarkdefaults_favicon_support.png \
   res/drawable/bookmarkdefaults_favicon_addons.png \
   $(addprefix res/drawable-mdpi/,$(notdir $(SYNC_RES_DRAWABLE_MDPI))) \
   $(NULL)
 
 RES_DRAWABLE_LDPI = \
   $(addprefix res/drawable-ldpi/,$(notdir $(SYNC_RES_DRAWABLE_LDPI))) \
@@ -416,16 +417,17 @@ RES_DRAWABLE_HDPI = \
   res/drawable-hdpi/doorhanger_arrow.png \
   res/drawable-hdpi/doorhanger_bg.9.png \
   res/drawable-hdpi/doorhanger_shadow_bg.9.png \
   res/drawable-hdpi/doorhanger_popup_bg.9.png \
   res/drawable-hdpi/site_security_identified.png \
   res/drawable-hdpi/site_security_verified.png \
   res/drawable-hdpi/urlbar_stop.png \
   res/drawable-hdpi/validation_arrow.png \
+  res/drawable-hdpi/validation_arrow_inverted.png \
   res/drawable-hdpi/validation_bg.9.png \
   $(addprefix res/drawable-hdpi/,$(notdir $(SYNC_RES_DRAWABLE_HDPI))) \
   $(NULL)
 
 RES_DRAWABLE_MDPI_V11 = \
   res/drawable-mdpi-v11/ic_menu_bookmark_add.png \
   res/drawable-mdpi-v11/ic_menu_bookmark_remove.png \
   res/drawable-mdpi-v11/ic_menu_find_in_page.png \
@@ -479,16 +481,17 @@ RES_DRAWABLE_XHDPI_V11 = \
   res/drawable-xhdpi-v11/address_bar_texture_port.png \
   res/drawable-xhdpi-v11/address_bar_url_bg.9.png \
   res/drawable-xhdpi-v11/address_bar_url_outline.9.png \
   res/drawable-xhdpi-v11/urlbar_stop.png \
   res/drawable-xhdpi-v11/site_security_identified.png \
   res/drawable-xhdpi-v11/site_security_verified.png \
   res/drawable-xhdpi-v11/tabs_button_tail.9.png \
   res/drawable-xhdpi-v11/validation_arrow.png \
+  res/drawable-xhdpi-v11/validation_arrow_inverted.png \
   res/drawable-xhdpi-v11/validation_bg.9.png \
   $(NULL)
 
 RES_DRAWABLE_LAND_V14 = \
   res/drawable-land-v14/address_bar_bg.xml \
   $(NULL)
 
 RES_DRAWABLE_LAND_MDPI_V14 = \
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..8cad658d8906ce115bedd7c88b791198fe99d5d0
GIT binary patch
literal 378
zc$@)x0fqjFP)<h;3K|Lk000e1NJLTq001Na000jN1^@s6jB9Oe0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUz97#k$RCwBAv~%`kV_;w~0pctmjs#*R
z2Ks}~Ks*VE7lSPS1;odII0lGqf%qYv9kUOJHGsGVh;O2Y2FPJXKzy7|j+qL?Zb1AD
zCV(w^-T|>Y5Fe(oW4eJj2Z;Y73o_w}Qx72CLnFtu0&y8O3496o8xZ>f@ir<urV5%~
z7)W&x2>bxzKp@^g1&90x;u0Wk$ES#xEDp+rVL-f+LdWC+aW5f-#Fja~fjAn77m?u@
zP@+wP<|u-Ig+zlBf%qp7r;?y20f?6nYYC~P@;@L>2jU4tMs*}9jv>cEu=G#}#IZp9
z1&5m3Kx_lVt4TGSl6ni|b2T9D1mdee{03UWgA%VE5T7Q;P{#lN|1%6Gz{D`f06>5N
Y08_&_5ijgXO8@`>07*qoM6N<$f^7<pC;$Ke
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..5b772c2c433a73ad9a07ddce7a180cff1d8e86eb
GIT binary patch
literal 480
zc$@*?0U!Q}P)<h;3K|Lk000e1NJLTq001xm000yS1^@s6%Rj!S0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzf=NU{RCwCdmd`6hQ547DoLJiU8!WBt
zP{N>O;nzZbER=<XwLifhU_r6AkR+i<SXz-r<VQ3mhDKx|V(@%!U8R?KGw<DN=FO?k
zTfBGfJ>PTgyXW3mL%hA*ahz%xfKjM$qHiZK39G^*0|zh;RWKi6;m<Ip3qAuW@i?TR
zU$4Yl#KfOLElk7L&r8YTJPRH05)tuxPzOie58^Xu8#*J9#6Gmb<6j>o$KWmKhSwsA
zS9`M!p0YVe9+PZBPZ9P+!msi{5>U3GSK_@u;t#d>hg^;lVA6HyEkF{-&;s}QI7`6E
z*P!nolTZg#bH3ukB%o|rpA{L);!m~sbdW(3GT4&7dVE+Ce-3fD3p!8?f-b@!d>V?s
z(3MYx87zju7huRBiA!jLo3H}J!t$%j-*AW|lDhKOCc(whKRgFrekZ2KcA*}wOaqI>
zE}~j&4ea>%sP;Pnjc{utXqn|!nAF`w-Cstu&`P~gS76FU)qh*ebzP^Ft>hE<7GMBv
W7gC{a;)Y%T0000<MNUMnLSTZ>ht-_`
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..88c892864da9d7a900353df26d7af89ceebac699
GIT binary patch
literal 244
zc%17D@N?(olHy`uVBq!ia0vp^5<tww!3HGPWzNe0Qj#UE5hcO-X(i=}MX3yqDfvmM
z3ZA)%>8U}fi7AzZCsS>Jil%wGIEGZ*O4?HV?MYff!UxtzVhUkt3*>Gv99iq*@JL%=
zJwuYR!aX0>=KoBEW&-R?A0^dPI{h7Fc#dRin%Ky7EI-IH<ATT^wnrXDx{Z?iL?S0}
zb~_d69L%!N<M!Cfvi#u>9ffN`d)kCIG2EQAGvbNEN`0C6506AJY*u0IXm0pnAYjk%
r=%_=EgO7mGzyJT|H%?<vIKUwINPYXn=S_=%E@bd@^>bP0l+XkKSl3re
--- a/mobile/android/base/resources/layout/validation_message.xml
+++ b/mobile/android/base/resources/layout/validation_message.xml
@@ -1,28 +1,38 @@
 <?xml version="1.0" encoding="utf-8"?>
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                 android:layout_width="wrap_content"
-                android:layout_height="fill_parent">
+                android:layout_height="50dip">
 
     <TextView android:id="@+id/validation_message_text"
               android:layout_width="wrap_content"
               android:layout_height="40dip"
               android:layout_marginTop="6dip"
               android:paddingLeft="20dp"
               android:paddingRight="20dp"
               android:textAppearance="?android:attr/textAppearanceSmall"
               android:textColor="@color/validation_message_text"
               android:background="@drawable/validation_bg"
               android:gravity="center"
               android:singleLine="true"
               android:scrollHorizontally="true"
-              android:ellipsize="marquee"
-              android:layout_alignParentTop="true"/>
+              android:ellipsize="marquee"/>
 
-    <ImageView android:layout_width="24dip"
+    <ImageView android:id="@+id/validation_message_arrow"
+               android:layout_width="24dip"
                android:layout_height="10dip"
                android:layout_centerHorizontal="true"
                android:layout_alignParentTop="true"
                android:src="@drawable/validation_arrow"
                android:scaleType="fitXY"/>
 
+    <ImageView android:id="@+id/validation_message_arrow_inverted"
+               android:layout_width="24dip"
+               android:layout_height="10dip"
+               android:layout_centerHorizontal="true"
+               android:layout_marginTop="35dip"
+               android:layout_alignParentTop="true"
+               android:src="@drawable/validation_arrow_inverted"
+               android:scaleType="fitXY"
+               android:visibility="gone"/>
+
 </RelativeLayout>