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