Bug 1105472 - Part 2: Add FadedMultiColorTextView. r=bnicholson
authorMichael Comella <michael.l.comella@gmail.com>
Wed, 31 Dec 2014 12:31:17 -0800
changeset 247603 2a4ba57bf69f5f85b5dd72c3a059c30e23c357c3
parent 247602 7cbfc2f0ee8671953fc6a153fbdc65b49d2eb7fd
child 247604 2e9b1569f4c85cad19ade8903482e3c35a47582f
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbnicholson
bugs1105472
milestone37.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 1105472 - Part 2: Add FadedMultiColorTextView. r=bnicholson
mobile/android/base/moz.build
mobile/android/base/resources/color/toolbar_display_layout_bg.xml
mobile/android/base/resources/layout/toolbar_display_layout.xml
mobile/android/base/resources/values/attrs.xml
mobile/android/base/widget/FadedMultiColorTextView.java
--- 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/FadedMultiColorTextView.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',
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/resources/color/toolbar_display_layout_bg.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- These colors are defined from the drawables url_bar_entry_default_* -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+          xmlns:gecko="http://schemas.android.com/apk/res-auto">
+
+    <item gecko:state_private="true" android:color="#080A0B"/>
+
+    <item android:color="#FFFFFF"/>
+
+</selector>
--- 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.FadedSingleColorTextView
+    <org.mozilla.gecko.widget.FadedMultiColorTextView
             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:fadeBackgroundColor="@color/toolbar_display_layout_bg"
             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"/>
 
--- a/mobile/android/base/resources/values/attrs.xml
+++ b/mobile/android/base/resources/values/attrs.xml
@@ -141,16 +141,22 @@
     <declare-styleable name="HomePagerTabStrip">
         <attr name="tabIndicatorColor" format="color"/>
     </declare-styleable>
 
     <declare-styleable name="FadedTextView">
         <attr name="fadeWidth" format="dimension"/>
     </declare-styleable>
 
+    <declare-styleable name="FadedMultiColorTextView">
+        <!-- The background color we should be fading over. Useful because the
+             background is full alpha and we need to copy the background underneath. -->
+        <attr name="fadeBackgroundColor" format="dimension"/>
+    </declare-styleable>
+
     <declare-styleable name="BookmarkFolderView">
         <attr name="state_open" format="boolean"/>
     </declare-styleable>
 
     <declare-styleable name="GeckoView">
         <attr name="url" format="string"/>
         <attr name="doinit" format="boolean"/>
     </declare-styleable>
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/widget/FadedMultiColorTextView.java
@@ -0,0 +1,104 @@
+/* -*- 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 org.mozilla.gecko.R;
+
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.LinearGradient;
+import android.graphics.Paint;
+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
+ * but potentially slower than the {@link org.mozilla.gecko.widget.FadedSingleColorTextView}.
+ * It works for text of multiple colors but only one background color. It works by
+ * drawing a gradient rectangle with the background color over the text, fading it out.
+ */
+public class FadedMultiColorTextView extends FadedTextView {
+    private final ColorStateList fadeBackgroundColorList;
+
+    private final Paint fadePaint;
+    private FadedTextGradient backgroundGradient;
+
+    public FadedMultiColorTextView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        fadePaint = new Paint();
+
+        final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FadedMultiColorTextView);
+        fadeBackgroundColorList =
+                a.getColorStateList(R.styleable.FadedMultiColorTextView_fadeBackgroundColor);
+        a.recycle();
+    }
+
+    @Override
+    public void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+
+        final boolean needsEllipsis = needsEllipsis();
+        if (needsEllipsis) {
+            final int right = getWidth() - getCompoundPaddingRight();
+            final float left = right - fadeWidth;
+
+            updateGradientShader(needsEllipsis, right);
+
+            final float center = getHeight() / 2;
+            final float top = center - getTextSize();
+            final float bottom = center + getTextSize();
+
+            canvas.drawRect(left, top, right, bottom, fadePaint);
+        }
+    }
+
+    private void updateGradientShader(final boolean needsEllipsis, final int gradientEndRight) {
+        final int backgroundColor =
+                fadeBackgroundColorList.getColorForState(getDrawableState(), Color.RED);
+
+        final boolean needsNewGradient = (backgroundGradient == null ||
+                                          backgroundGradient.getBackgroundColor() != backgroundColor ||
+                                          backgroundGradient.getEndRight() != gradientEndRight);
+
+        if (needsEllipsis && needsNewGradient) {
+            backgroundGradient = new FadedTextGradient(gradientEndRight, fadeWidth, backgroundColor);
+            fadePaint.setShader(backgroundGradient);
+        }
+    }
+
+    private static class FadedTextGradient extends LinearGradient {
+        private final int endRight;
+        private final int backgroundColor;
+
+        public FadedTextGradient(final int gradientEndRight, final int fadeWidth,
+                final int backgroundColor) {
+            super(gradientEndRight - fadeWidth, 0, gradientEndRight, 0,
+                  getColorWithZeroedAlpha(backgroundColor), backgroundColor, Shader.TileMode.CLAMP);
+
+            this.endRight = gradientEndRight;
+            this.backgroundColor = backgroundColor;
+        }
+
+        private static int getColorWithZeroedAlpha(final int color) {
+            return Color.argb(0, Color.red(color), Color.green(color), Color.blue(color));
+        }
+
+        public int getEndRight() {
+            return endRight;
+        }
+
+        public int getBackgroundColor() {
+            return backgroundColor;
+        }
+    }
+}