Bug 837113: Close button in tabs ui. [r=mfinkle] [a=lsblakk]
authorSriram Ramasubramanian <sriram@mozilla.com>
Thu, 14 Feb 2013 13:23:15 -0800
changeset 123990 8ec33ec55ff56b0e46626c49b052d70e4b5e62e7
parent 123989 66dd13c06cdf04de93c04d0f5bb484cdc37633fe
child 123991 359388a5aa75988019dce39923432c8f0fd754a0
push id3368
push usersramasubramanian@mozilla.com
push dateFri, 15 Feb 2013 23:21:53 +0000
treeherdermozilla-aurora@8ec33ec55ff5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle, lsblakk
bugs837113
milestone20.0a2
Bug 837113: Close button in tabs ui. [r=mfinkle] [a=lsblakk]
mobile/android/base/TabsTray.java
mobile/android/base/resources/drawable-hdpi/tab_close.png
mobile/android/base/resources/drawable-xhdpi/tab_close.png
mobile/android/base/resources/drawable/tab_close.png
mobile/android/base/resources/layout-xlarge-v11/tabs_row.xml
mobile/android/base/resources/layout/tabs_row.xml
--- a/mobile/android/base/TabsTray.java
+++ b/mobile/android/base/TabsTray.java
@@ -71,16 +71,17 @@ public class TabsTray extends ListView
         setOnTouchListener(mSwipeListener);
         setOnScrollListener(mSwipeListener.makeScrollListener());
 
         setRecyclerListener(new RecyclerListener() {
             @Override
             public void onMovedToScrapHeap(View view) {
                 TabRow row = (TabRow) view.getTag();
                 row.thumbnail.setImageDrawable(null);
+                row.close.setVisibility(View.VISIBLE);
             }
         });
     }
 
     @Override
     public ViewGroup getLayout() {
         return this;
     }
@@ -110,22 +111,24 @@ public class TabsTray extends ListView
         mTabsPanel.autoHidePanel();
     }
 
     // ViewHolder for a row in the list
     private class TabRow {
         int id;
         TextView title;
         ImageView thumbnail;
+        ImageButton close;
         LinearLayout info;
 
         public TabRow(View view) {
             info = (LinearLayout) view;
             title = (TextView) view.findViewById(R.id.title);
             thumbnail = (ImageView) view.findViewById(R.id.thumbnail);
+            close = (ImageButton) view.findViewById(R.id.close);
         }
     }
 
     // Adapter to bind tabs into a list
     private class TabsAdapter extends BaseAdapter implements Tabs.OnTabsChangedListener {
         private Context mContext;
         private boolean mIsPrivate;
         private ArrayList<Tab> mTabs;
@@ -237,24 +240,26 @@ public class TabsTray extends ListView
             if (thumbnailImage != null)
                 row.thumbnail.setImageDrawable(thumbnailImage);
             else if (TextUtils.equals(tab.getURL(), ABOUT_HOME))
                 row.thumbnail.setImageResource(R.drawable.abouthome_thumbnail);
             else
                 row.thumbnail.setImageResource(R.drawable.tab_thumbnail_default);
 
             row.title.setText(tab.getDisplayTitle());
+            row.close.setTag(row);
         }
 
         public View getView(int position, View convertView, ViewGroup parent) {
             TabRow row;
 
             if (convertView == null) {
                 convertView = mInflater.inflate(R.layout.tabs_row, null);
                 row = new TabRow(convertView);
+                row.close.setOnClickListener(mOnCloseClickListener);
                 convertView.setTag(row);
             } else {
                 row = (TabRow) convertView.getTag();
             }
 
             Tab tab = mTabs.get(position);
             assignValues(row, tab);
 
@@ -317,16 +322,25 @@ public class TabsTray extends ListView
 
         animator.start();
     }
 
     private void animateCancel(final View view) {
         PropertyAnimator animator = new PropertyAnimator(ANIMATION_DURATION);
         animator.attach(view, Property.ALPHA, 1);
         animator.attach(view, Property.TRANSLATION_X, 0);
+
+        animator.setPropertyAnimationListener(new PropertyAnimator.PropertyAnimationListener() {
+            public void onPropertyAnimationStart() { }
+            public void onPropertyAnimationEnd() {
+                TabRow tab = (TabRow) view.getTag();
+                tab.close.setVisibility(View.VISIBLE);
+            }
+        });
+
         animator.start();
     }
 
     private class TabSwipeGestureListener implements View.OnTouchListener {
         // same value the stock browser uses for after drag animation velocity in pixels/sec
         // http://androidxref.com/4.0.4/xref/packages/apps/Browser/src/com/android/browser/NavTabScroller.java#61
         private static final float MIN_VELOCITY = 750;
 
@@ -466,16 +480,19 @@ public class TabsTray extends ListView
                     if (Math.abs(deltaX) > mSwipeThreshold) {
                         // If we're actually swiping, make sure we don't
                         // set pressed state on the swiped view.
                         cancelCheckForTap();
 
                         mSwiping = true;
                         TabsTray.this.requestDisallowInterceptTouchEvent(true);
 
+                        TabRow tab = (TabRow) mSwipeView.getTag();
+                        tab.close.setVisibility(View.INVISIBLE);
+
                         // Stops listview from highlighting the touched item
                         // in the list when swiping.
                         MotionEvent cancelEvent = MotionEvent.obtain(e);
                         cancelEvent.setAction(MotionEvent.ACTION_CANCEL |
                                 (e.getActionIndex() << MotionEvent.ACTION_POINTER_INDEX_SHIFT));
                         TabsTray.this.onTouchEvent(cancelEvent);
 
                         mSwipeProxy = AnimatorProxy.create(mSwipeView);
index e135e341e2a66bc1083b9ea2d62fab69076dc24a..8d354d2741363e1f7f320921818326daedc0ab6a
GIT binary patch
literal 208
zc%17D@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@Rhe>7Fi*Ar-fJuQ+lw8;H1G^e>f{
z-Kp)mX4)=6_N5Q*TwRvGz{Y*&|HE@VY$mV>&GP$uWrf_t`EF-lt)8b<RyxP`n843F
z|89ru`Fk*etFXB%Y^`X|gz49r+&naou4c&2?od3yVCW*D(DrEtzZrj}^>?)v3B$JN
z)pyQuNhn|cDtzpOWkagqu@IdOgKMjA2qxw<xASg%T6N>!Md8J*>>pbkflg%bboFyt
I=akR{00`Jqd;kCd
index 06b539a4bf7142b25a98a4a10da514e1778d542f..1c790a66774e073957ab673308a4860dd877fb18
GIT binary patch
literal 259
zc%17D@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`Gjr#xL8Ln>}9z2?Z*WFX>t(f-A%
zDUafM^4JT*!n*4VCR+u>%bQhldhJM0G59p)j_vkmSv>P<@7wnso1Dg}XLhaVb6`XI
z?dbQ@y4mGrT#grSd3=VKJ+M&f=CcrC$<FY1#|2X~?lH<={KzNKA<6zhK%MV_V*I|@
z99j;_eliD~OYX2glRu!tVEj(GY|qBPBYplmvlQ}T{`-j(O#E24jPXgqoOaVk$E_C#
zHoQ8<XmW@<z4S4I)WfNjKuTz#Y-_h_`LFN!+`X-7m5f5OA7!4qw_gkBD+W(jKbLh*
G2~7a5+Gk1t
index a8f89c935f207a15e6046057f2a913db62c33f04..e6cc9ae973f539451bac53aef2140b4f996e5a86
GIT binary patch
literal 158
zc%17D@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a)4R8JSjkcwNS6F2fUIPfs<WjNJ+
zQsd=}$J{J`x)pDTiN9R5x#aH74&~<t{h5!}q|Lhf!fd|evc^BlE>FFru~aKQEl@41
zGgYI}M|Hwa2bm_mCyEul4MOW3mqw<@Jqp>kd$~{Nl<o3c7?mqFxbK<<w2;Bm)z4*}
HQ$iB}nsq!Y
--- a/mobile/android/base/resources/layout-xlarge-v11/tabs_row.xml
+++ b/mobile/android/base/resources/layout-xlarge-v11/tabs_row.xml
@@ -1,15 +1,16 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- 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/. -->
 
 <Gecko.TabRow xmlns:android="http://schemas.android.com/apk/res/android"
               android:focusable="true"
+              android:nextFocusRight="@+id/close"
               android:id="@+id/info"
               android:layout_width="fill_parent"
               android:layout_height="wrap_content"
               android:padding="6dip"
               android:gravity="center"
               android:background="@drawable/tab_row">
 
     <RelativeLayout android:layout_width="wrap_content"
@@ -19,23 +20,41 @@
                     android:background="@drawable/tab_thumbnail"
                     android:duplicateParentState="true">
 
         <Gecko.ThumbnailView android:id="@+id/thumbnail"
                              android:layout_width="@dimen/tab_thumbnail_width"
                              android:layout_height="@dimen/tab_thumbnail_height"
                              android:src="@drawable/tab_thumbnail_default"/>
 
-        <TextView android:id="@+id/title"
-                  android:layout_width="@dimen/tab_thumbnail_width"
-                  android:layout_height="wrap_content"
-                  android:layout_alignParentBottom="true"
-                  android:padding="4dip"
-                  style="@style/TabRowTextAppearance"
-                  android:background="#B3FFFFFF"
-                  android:textSize="12sp"
-                  android:textColor="#FF222222"
-                  android:singleLine="true"
-                  android:duplicateParentState="true"/>
+
+        <LinearLayout android:layout_width="@dimen/tab_thumbnail_width"
+                      android:layout_height="wrap_content"
+                      android:orientation="horizontal"
+                      android:background="#B3FFFFFF"
+                      android:layout_alignParentBottom="true"
+                      android:duplicateParentState="true">
+
+            <TextView android:id="@+id/title"
+                      android:layout_width="0dip"
+                      android:layout_height="wrap_content"
+                      android:layout_weight="1.0"
+                      android:padding="4dip"
+                      style="@style/TabRowTextAppearance"
+                      android:textSize="12sp"
+                      android:textColor="#FF222222"
+                      android:singleLine="true"
+                      android:duplicateParentState="true"/>
+
+            <ImageButton android:id="@+id/close"
+                         android:nextFocusLeft="@+id/info"
+                         android:layout_width="32dip"
+                         android:layout_height="fill_parent"
+                         android:background="@drawable/action_bar_button"
+                         android:scaleType="center"
+                         android:contentDescription="@string/close_tab"
+                         android:src="@drawable/tab_close"/>
+
+        </LinearLayout>
 
     </RelativeLayout>
 
 </Gecko.TabRow>
--- a/mobile/android/base/resources/layout/tabs_row.xml
+++ b/mobile/android/base/resources/layout/tabs_row.xml
@@ -1,20 +1,20 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- 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/. -->
 
 <Gecko.TabRow xmlns:android="http://schemas.android.com/apk/res/android"
               android:focusable="true"
+              android:nextFocusRight="@+id/close"
               android:id="@+id/info"
               android:layout_width="fill_parent"
               android:layout_height="wrap_content"
               android:paddingLeft="12dip"
-              android:paddingRight="12dip"
               android:paddingTop="6dip"
               android:paddingBottom="6dip"
               android:background="@drawable/tab_row">
 
     <LinearLayout android:layout_width="wrap_content"
                   android:layout_height="wrap_content"
                   android:padding="4dip"
                   android:background="@drawable/tab_thumbnail"
@@ -36,9 +36,18 @@
               android:paddingRight="4dip"
               style="@style/TabRowTextAppearance"
               android:textColor="#FFFFFFFF"
               android:textSize="14sp"
               android:singleLine="false"
               android:maxLines="4"
               android:duplicateParentState="true"/>
 
+    <ImageButton android:id="@+id/close"
+                 android:nextFocusLeft="@+id/info"
+                 android:layout_width="34dip"
+                 android:layout_height="fill_parent"
+                 android:background="@drawable/action_bar_button"
+                 android:scaleType="center"
+                 android:contentDescription="@string/close_tab"
+                 android:src="@drawable/tab_close"/>
+
 </Gecko.TabRow>