Home | History | Annotate | Download | only in browse
      1 /*
      2  * Copyright (C) 2014 Google Inc.
      3  * Licensed to The Android Open Source Project.
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 package com.android.mail.browse;
     19 
     20 import android.graphics.Canvas;
     21 import android.graphics.Paint;
     22 import android.graphics.Paint.FontMetricsInt;
     23 import android.graphics.RectF;
     24 import android.text.Spanned;
     25 import android.text.TextPaint;
     26 import android.text.style.CharacterStyle;
     27 import android.text.style.ReplacementSpan;
     28 
     29 /**
     30  * A replacement span to use when displaying a badge in a conversation list item.
     31  * A badge will be some piece of text with a colored background and rounded
     32  * corners.
     33  */
     34 public class BadgeSpan extends ReplacementSpan {
     35 
     36     public interface BadgeSpanDimensions {
     37         /**
     38          * Returns the padding value that corresponds to one side of the
     39          * horizontal padding surrounding the text inside the background color.
     40          */
     41         int getHorizontalPadding();
     42 
     43         /**
     44          * Returns the radius to use for the rounded corners on the background rect.
     45          */
     46         float getRoundedCornerRadius();
     47     }
     48 
     49     private TextPaint mWorkPaint = new TextPaint();
     50     /**
     51      * A reference to the enclosing Spanned object to collect other CharacterStyle spans and take
     52      * them into account when drawing.
     53      */
     54     private final Spanned mSpanned;
     55     private final BadgeSpanDimensions mDims;
     56 
     57     public BadgeSpan(Spanned spanned, BadgeSpanDimensions dims) {
     58         mSpanned = spanned;
     59         mDims = dims;
     60     }
     61 
     62     @Override
     63     public int getSize(Paint paint, CharSequence text, int start, int end, FontMetricsInt fm) {
     64         if (fm != null) {
     65             paint.getFontMetricsInt(fm);
     66             // The magic set of measurements to vertically center text within a colored region!
     67             fm.top = fm.ascent;
     68         }
     69         return measureWidth(paint, text, start, end);
     70     }
     71 
     72     private int measureWidth(Paint paint, CharSequence text, int start, int end) {
     73         return (int) paint.measureText(text, start, end) + 2 * mDims.getHorizontalPadding();
     74     }
     75 
     76     @Override
     77     public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top,
     78             int y, int bottom, Paint paint) {
     79 
     80         mWorkPaint.set(paint);
     81 
     82         // take into account the foreground/background color spans when painting
     83         final CharacterStyle[] otherSpans = mSpanned.getSpans(start, end, CharacterStyle.class);
     84         for (CharacterStyle otherSpan : otherSpans) {
     85             otherSpan.updateDrawState(mWorkPaint);
     86         }
     87 
     88         // paint a background if present
     89         if (mWorkPaint.bgColor != 0) {
     90             final int prevColor = mWorkPaint.getColor();
     91             final Paint.Style prevStyle = mWorkPaint.getStyle();
     92 
     93             mWorkPaint.setColor(mWorkPaint.bgColor);
     94             mWorkPaint.setStyle(Paint.Style.FILL);
     95 
     96             final int bgWidth = measureWidth(mWorkPaint, text, start, end);
     97             final RectF rect = new RectF(x, top, x + bgWidth, bottom);
     98             final float radius = mDims.getRoundedCornerRadius();
     99             canvas.drawRoundRect(rect, radius, radius, mWorkPaint);
    100 
    101             mWorkPaint.setColor(prevColor);
    102             mWorkPaint.setStyle(prevStyle);
    103         }
    104 
    105         canvas.drawText(text, start, end, x + mDims.getHorizontalPadding(), y, mWorkPaint);
    106     }
    107 }
    108