Home | History | Annotate | Download | only in phone
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.phone;
     18 
     19 import android.content.Context;
     20 import android.content.res.TypedArray;
     21 import android.graphics.drawable.Drawable;
     22 import android.text.TextUtils.TruncateAt;
     23 import android.util.Log;
     24 import android.view.Gravity;
     25 import android.widget.TextView;
     26 
     27 
     28 /**
     29  * The View for each item in the {@link InCallMenuView}.
     30  *
     31  * Each in-call menu item has a text label, an optional "green LED" on/off
     32  * indicator below the text, and an optional icon above the text.
     33  * (It's really just a TextView, using "compound drawables" for
     34  * the indicator and icon.)
     35  *
     36  * Originally modeled after android/widget/IconMenuItemView.java.
     37  */
     38 class InCallMenuItemView extends TextView {
     39     private static final String LOG_TAG = "PHONE/InCallMenuItemView";
     40     private static final boolean DBG = false;
     41 
     42     private boolean mIndicatorVisible;
     43     private boolean mIndicatorState;
     44     private Drawable mIndicatorDrawable;
     45     private Drawable mIcon;
     46 
     47     public InCallMenuItemView(Context context) {
     48         super(context);
     49         if (DBG) log("InCallMenuView constructor...");
     50 
     51         setGravity(Gravity.CENTER);
     52 
     53         TypedArray a =
     54                 context.obtainStyledAttributes(
     55                         com.android.internal.R.styleable.MenuView);
     56         int textAppearance = a.getResourceId(com.android.internal.R.styleable.
     57                                              MenuView_itemTextAppearance, -1);
     58         // TODO: any other styleable attrs we need from the standard menu item style?
     59         a.recycle();
     60 
     61         setClickable(true);
     62         setFocusable(true);
     63         setTextAppearance(context, textAppearance);
     64 
     65         // Set the padding like the regular menu items do
     66         setPadding(3, getPaddingTop(), 3, getPaddingBottom());
     67     }
     68 
     69     //
     70     // Visibility: we only ever use the VISIBLE and GONE states.
     71     //
     72 
     73     public void setVisible(boolean isVisible) {
     74         setVisibility(isVisible ? VISIBLE : GONE);
     75     }
     76 
     77     public boolean isVisible() {
     78         return (getVisibility() == VISIBLE);
     79     }
     80 
     81     /**
     82      * Sets whether or not this item's "green LED" state indicator
     83      * should be visible.
     84      */
     85     public void setIndicatorVisible(boolean isVisible) {
     86         if (DBG) log("setIndicatorVisible(" + isVisible + ")...");
     87         mIndicatorVisible = isVisible;
     88         updateIndicator();
     89         updateCompoundDrawables();
     90     }
     91 
     92     /**
     93      * Turns this item's "green LED" state indicator on or off.
     94      */
     95     public void setIndicatorState(boolean onoff) {
     96         if (DBG) log("setIndicatorState(" + onoff + ")...");
     97         mIndicatorState = onoff;
     98         updateIndicator();
     99         updateCompoundDrawables();
    100     }
    101 
    102     /**
    103      * Sets this item's icon, to be drawn above the text label.
    104      */
    105     public void setIcon(Drawable icon) {
    106         if (DBG) log("setIcon(" + icon + ")...");
    107         mIcon = icon;
    108         updateCompoundDrawables();
    109 
    110         // If there's an icon, we'll only have enough room for one line of text.
    111         if (icon != null) setSingleLineMarquee();
    112     }
    113 
    114     /**
    115      * Sets this item's icon, to be drawn above the text label.
    116      */
    117     public void setIconResource(int resId) {
    118         if (DBG) log("setIconResource(" + resId + ")...");
    119          Drawable iconDrawable = getResources().getDrawable(resId);
    120          setIcon(iconDrawable);
    121     }
    122 
    123     /**
    124      * Updates mIndicatorDrawable based on mIndicatorVisible and mIndicatorState.
    125      */
    126     private void updateIndicator() {
    127         if (mIndicatorVisible) {
    128             int resId = mIndicatorState ? android.R.drawable.button_onoff_indicator_on
    129                     : android.R.drawable.button_onoff_indicator_off;
    130             mIndicatorDrawable = getResources().getDrawable(resId);
    131         } else {
    132             mIndicatorDrawable = null;
    133         }
    134     }
    135 
    136     /**
    137      * Installs mIcon and mIndicatorDrawable as our TextView "compound drawables",
    138      * and does any necessary layout tweaking depending on the presence or
    139      * absence of the icon or indicator.
    140      */
    141     private void updateCompoundDrawables() {
    142         // TODO: There are several hand-tweaked layout constants hardcoded here.
    143         // If we ever move this widget into the framework (and make it
    144         // usable from XML), be sure to move these constants to XML too.
    145 
    146         // If the icon is visible, add a bit of negative padding to scoot
    147         // it down closer to the text.
    148         if (mIcon != null) {
    149             setCompoundDrawablePadding(-10);
    150         }
    151 
    152         // Add some top/bottom padding when the indicator and/or icon are
    153         // visible (to add a little vertical space between the indicator
    154         // and the bottom of the item, or the icon and the top of the
    155         // item.)
    156         int topPadding = (mIcon != null) ? 5 : 0;
    157         int bottomPadding = (mIndicatorDrawable != null) ? 5 : 0;
    158         setPadding(0, topPadding, 0, bottomPadding);
    159 
    160         // TODO: topPadding seems to have no effect here.
    161         // Regardless of the value I use, the icon image
    162         // ends up right up against the top edge of the button...
    163         // (Maybe we're just out of room?)
    164         // if (DBG) log("updateCompoundDrawables: padding: top " + topPadding
    165         //              + ", bottom " + bottomPadding);
    166 
    167         setCompoundDrawablesWithIntrinsicBounds(null, mIcon, null, mIndicatorDrawable);
    168     }
    169 
    170     /**
    171      * Forces this menu item into "single line" mode, with marqueeing enabled.
    172      * This is only necessary when an icon is present, since otherwise
    173      * there's enough room for long labels to wrap onto two lines.
    174      */
    175     private void setSingleLineMarquee() {
    176         setEllipsize(TruncateAt.MARQUEE);
    177         setHorizontalFadingEdgeEnabled(true);
    178         setSingleLine(true);
    179     }
    180 
    181     @Override
    182     public String toString() {
    183         return "'" + getText() + "' (" + super.toString() + ")";
    184     }
    185 
    186     private void log(String msg) {
    187         Log.d(LOG_TAG, msg);
    188     }
    189 }
    190