Bug 1105472 - Part 1: Make FadedTextView abstract and move current implementation to FadedSingleColorTextView. r=bnicholson
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -468,16 +468,17 @@ gbjar.sources += [
'widget/BasicColorPicker.java',
'widget/ButtonToast.java',
'widget/CheckableLinearLayout.java',
'widget/ClickableWhenDisabledEditText.java',
'widget/DateTimePicker.java',
'widget/Divider.java',
'widget/DoorHanger.java',
'widget/EllipsisTextView.java',
+ 'widget/FadedSingleColorTextView.java',
'widget/FadedTextView.java',
'widget/FaviconView.java',
'widget/FloatingHintEditText.java',
'widget/FlowLayout.java',
'widget/GeckoActionProvider.java',
'widget/GeckoPopupMenu.java',
'widget/GeckoSwipeRefreshLayout.java',
'widget/GeckoViewFlipper.java',
--- a/mobile/android/base/resources/layout-large-v11/tab_strip_item_view.xml
+++ b/mobile/android/base/resources/layout-large-v11/tab_strip_item_view.xml
@@ -9,17 +9,17 @@
<ImageView
android:id="@+id/favicon"
android:layout_width="@dimen/new_tablet_tab_strip_favicon_size"
android:layout_height="match_parent"
android:layout_marginRight="8dp"
android:scaleType="centerInside"
android:duplicateParentState="true"/>
- <org.mozilla.gecko.widget.FadedTextView
+ <org.mozilla.gecko.widget.FadedSingleColorTextView
android:id="@+id/title"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1.0"
android:layout_marginRight="-5dp"
android:gravity="center_vertical"
android:textSize="14sp"
android:ellipsize="end"
--- a/mobile/android/base/resources/layout-v11/new_tablet_tabs_item_cell.xml
+++ b/mobile/android/base/resources/layout-v11/new_tablet_tabs_item_cell.xml
@@ -16,27 +16,28 @@
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:duplicateParentState="true"
android:paddingLeft="@dimen/new_tablet_tab_highlight_stroke_width"
android:paddingRight="@dimen/new_tablet_tab_highlight_stroke_width"
android:paddingBottom="@dimen/new_tablet_tab_highlight_stroke_width">
- <org.mozilla.gecko.widget.FadedTextView android:id="@+id/title"
- android:layout_width="0dip"
- android:layout_height="wrap_content"
- android:layout_weight="1.0"
- style="@style/TabLayoutItemTextAppearance"
- android:textSize="14sp"
- android:textColor="@color/new_tablet_tab_item_title"
- android:singleLine="true"
- android:duplicateParentState="true"
- gecko:fadeWidth="15dp"
- android:paddingRight="5dp"/>
+ <org.mozilla.gecko.widget.FadedSingleColorTextView
+ android:id="@+id/title"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1.0"
+ style="@style/TabLayoutItemTextAppearance"
+ android:textSize="14sp"
+ android:textColor="@color/new_tablet_tab_item_title"
+ android:singleLine="true"
+ android:duplicateParentState="true"
+ gecko:fadeWidth="15dp"
+ android:paddingRight="5dp"/>
<!-- Use of baselineAlignBottom only supported from API 11+ - if this needs to work on lower API versions
we'll need to override getBaseLine() and return image height, but we assume this won't happen -->
<ImageButton android:id="@+id/close"
style="@style/TabsItemClose"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
--- a/mobile/android/base/resources/layout/home_remote_tabs_group.xml
+++ b/mobile/android/base/resources/layout/home_remote_tabs_group.xml
@@ -24,17 +24,17 @@
tools:src="@drawable/sync_mobile"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
- <org.mozilla.gecko.widget.FadedTextView
+ <org.mozilla.gecko.widget.FadedSingleColorTextView
android:id="@+id/client"
style="@style/Widget.TwoLinePageRow.Title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
gecko:fadeWidth="30dp"
tools:text="Firefox on Nexus 5"/>
<TextView
--- a/mobile/android/base/resources/layout/tab_history_item_row.xml
+++ b/mobile/android/base/resources/layout/tab_history_item_row.xml
@@ -35,17 +35,17 @@
<ImageView android:id="@+id/tab_history_timeline_bottom"
android:layout_width="@dimen/tab_history_timeline_width"
android:layout_height="@dimen/tab_history_timeline_height"
android:layout_gravity="center_horizontal"
android:background="@color/tab_history_timeline_separator" />
</LinearLayout>
- <org.mozilla.gecko.widget.FadedTextView
+ <org.mozilla.gecko.widget.FadedSingleColorTextView
android:id="@+id/tab_history_title"
style="@style/Widget.TwoLinePageRow.Title"
android:layout_centerVertical="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingRight="@dimen/tab_history_title_margin_right"
android:text="@+id/tab_history_title"
--- a/mobile/android/base/resources/layout/toolbar_display_layout.xml
+++ b/mobile/android/base/resources/layout/toolbar_display_layout.xml
@@ -20,23 +20,24 @@
android:layout_width="@dimen/browser_toolbar_site_security_width"
android:scaleType="fitCenter"
android:layout_marginRight="4dip"
android:layout_marginBottom="@dimen/site_security_bottom_margin"
android:src="@drawable/site_security_level"
android:contentDescription="@string/site_security"
android:visibility="gone"/>
- <org.mozilla.gecko.widget.FadedTextView android:id="@+id/url_bar_title"
- style="@style/UrlBar.Title"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1.0"
- gecko:fadeWidth="40dip"
- gecko:autoUpdateTheme="false"/>
+ <org.mozilla.gecko.widget.FadedSingleColorTextView
+ android:id="@+id/url_bar_title"
+ style="@style/UrlBar.Title"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1.0"
+ gecko:fadeWidth="40dip"
+ gecko:autoUpdateTheme="false"/>
<org.mozilla.gecko.toolbar.PageActionLayout android:id="@+id/page_action_layout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:visibility="gone"
android:orientation="horizontal"/>
<ImageButton android:id="@+id/stop"
--- a/mobile/android/base/resources/layout/top_sites_grid_item_view.xml
+++ b/mobile/android/base/resources/layout/top_sites_grid_item_view.xml
@@ -7,17 +7,17 @@
xmlns:gecko="http://schemas.android.com/apk/res-auto">
<org.mozilla.gecko.home.TopSitesThumbnailView
android:id="@+id/thumbnail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"/>
- <org.mozilla.gecko.widget.FadedTextView
+ <org.mozilla.gecko.widget.FadedSingleColorTextView
android:id="@+id/title"
style="@style/Widget.TopSitesGridItemTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/thumbnail"
android:duplicateParentState="true"
android:drawablePadding="4dip"
gecko:fadeWidth="20dip"/>
--- a/mobile/android/base/resources/layout/two_line_page_row.xml
+++ b/mobile/android/base/resources/layout/two_line_page_row.xml
@@ -15,17 +15,17 @@
tools:background="@drawable/favicon"/>
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="vertical"
android:paddingRight="25dp">
- <org.mozilla.gecko.widget.FadedTextView
+ <org.mozilla.gecko.widget.FadedSingleColorTextView
android:id="@+id/title"
style="@style/Widget.TwoLinePageRow.Title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
gecko:fadeWidth="30dp"
tools:text="This is a long test title"/>
<TextView android:id="@+id/url"
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/widget/FadedSingleColorTextView.java
@@ -0,0 +1,74 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * 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/. */
+
+package org.mozilla.gecko.widget;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.LinearGradient;
+import android.graphics.Shader;
+import android.util.AttributeSet;
+
+/**
+ * Fades the end of the text by gecko:fadeWidth amount,
+ * if the text is too long and requires an ellipsis.
+ *
+ * This implementation is an improvement over Android's built-in fadingEdge
+ * and the fastest of Fennec's implementations. However, it only works for
+ * text of one color. It works by applying a linear gradient directly to the text.
+ */
+public class FadedSingleColorTextView extends FadedTextView {
+ // Shader for the fading edge.
+ private FadedTextGradient mTextGradient;
+
+ public FadedSingleColorTextView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ private void updateGradientShader() {
+ final int color = getCurrentTextColor();
+ final int width = getAvailableWidth();
+
+ final boolean needsNewGradient = (mTextGradient == null ||
+ mTextGradient.getColor() != color ||
+ mTextGradient.getWidth() != width);
+
+ final boolean needsEllipsis = needsEllipsis();
+ if (needsEllipsis && needsNewGradient) {
+ mTextGradient = new FadedTextGradient(width, fadeWidth, color);
+ }
+
+ getPaint().setShader(needsEllipsis ? mTextGradient : null);
+ }
+
+ @Override
+ public void onDraw(Canvas canvas) {
+ updateGradientShader();
+ super.onDraw(canvas);
+ }
+
+ private static class FadedTextGradient extends LinearGradient {
+ private final int mWidth;
+ private final int mColor;
+
+ public FadedTextGradient(int width, int fadeWidth, int color) {
+ super(0, 0, width, 0,
+ new int[] { color, color, 0x0 },
+ new float[] { 0, ((float) (width - fadeWidth) / width), 1.0f },
+ Shader.TileMode.CLAMP);
+
+ mWidth = width;
+ mColor = color;
+ }
+
+ public int getWidth() {
+ return mWidth;
+ }
+
+ public int getColor() {
+ return mColor;
+ }
+ }
+}
--- a/mobile/android/base/widget/FadedTextView.java
+++ b/mobile/android/base/widget/FadedTextView.java
@@ -2,104 +2,46 @@
* 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/. */
package org.mozilla.gecko.widget;
import android.content.Context;
import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.LinearGradient;
-import android.graphics.Shader;
-import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.util.AttributeSet;
import org.mozilla.gecko.R;
-import org.mozilla.gecko.widget.ThemedTextView;
/**
- * FadedTextView fades the ends of the text by fadeWidth amount,
- * if the text is too long and requires an ellipsis.
+ * An implementation of FadedTextView should fade the end of the text
+ * by gecko:fadeWidth amount, if the text is too long and requires an ellipsis.
*/
-public class FadedTextView extends ThemedTextView {
-
+public abstract class FadedTextView extends ThemedTextView {
// Width of the fade effect from end of the view.
- private final int mFadeWidth;
+ protected final int fadeWidth;
- // Shader for the fading edge.
- private FadedTextGradient mTextGradient;
-
- public FadedTextView(Context context) {
- this(context, null);
- }
-
- public FadedTextView(Context context, AttributeSet attrs) {
+ public FadedTextView(final Context context, final AttributeSet attrs) {
super(context, attrs);
setSingleLine(true);
setEllipsize(null);
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FadedTextView);
- mFadeWidth = a.getDimensionPixelSize(R.styleable.FadedTextView_fadeWidth, 0);
+ final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FadedTextView);
+ fadeWidth = a.getDimensionPixelSize(R.styleable.FadedTextView_fadeWidth, 0);
a.recycle();
}
- private int getAvailableWidth() {
+ protected int getAvailableWidth() {
return getWidth() - getCompoundPaddingLeft() - getCompoundPaddingRight();
}
- private boolean needsEllipsis() {
+ protected boolean needsEllipsis() {
final int width = getAvailableWidth();
if (width <= 0) {
return false;
}
final Layout layout = getLayout();
return (layout != null && layout.getLineWidth(0) > width);
}
-
- private void updateGradientShader() {
- final int color = getCurrentTextColor();
- final int width = getAvailableWidth();
-
- final boolean needsNewGradient = (mTextGradient == null ||
- mTextGradient.getColor() != color ||
- mTextGradient.getWidth() != width);
-
- final boolean needsEllipsis = needsEllipsis();
- if (needsEllipsis && needsNewGradient) {
- mTextGradient = new FadedTextGradient(width, mFadeWidth, color);
- }
-
- getPaint().setShader(needsEllipsis ? mTextGradient : null);
- }
-
- @Override
- public void onDraw(Canvas canvas) {
- updateGradientShader();
- super.onDraw(canvas);
- }
-
- private static class FadedTextGradient extends LinearGradient {
- private final int mWidth;
- private final int mColor;
-
- public FadedTextGradient(int width, int fadeWidth, int color) {
- super(0, 0, width, 0,
- new int[] { color, color, 0x0 },
- new float[] { 0, ((float) (width - fadeWidth) / width), 1.0f },
- Shader.TileMode.CLAMP);
-
- mWidth = width;
- mColor = color;
- }
-
- public int getWidth() {
- return mWidth;
- }
-
- public int getColor() {
- return mColor;
- }
- }
}