blob: 31aefe96a69a948ba1b15bf36d677007b61a390e [file] [log] [blame]
John Spurlockaf8d6c42014-05-07 17:49:08 -04001/*
2 * Copyright (C) 2014 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
17package com.android.systemui.qs;
18
19import android.content.Context;
20import android.content.res.Resources;
21import android.content.res.TypedArray;
22import android.graphics.Typeface;
23import android.graphics.drawable.Drawable;
24import android.os.Handler;
25import android.os.Looper;
26import android.os.Message;
27import android.util.TypedValue;
28import android.view.Gravity;
29import android.view.View;
30import android.view.ViewGroup;
John Spurlock83e28482014-05-18 17:20:05 -040031import android.widget.ImageView;
John Spurlockaf8d6c42014-05-07 17:49:08 -040032import android.widget.ImageView.ScaleType;
33import android.widget.TextView;
34
35import com.android.systemui.R;
36import com.android.systemui.qs.QSTile.State;
37
38/** View that represents a standard quick settings tile. **/
39public class QSTileView extends ViewGroup {
40 private static final Typeface CONDENSED = Typeface.create("sans-serif-condensed",
41 Typeface.NORMAL);
42 private static final int VERTICAL_PADDING_FACTOR = 8; // internal padding 1/8 the cell height
43
44 protected final Context mContext;
45 private final View mIcon;
46 private final View mDivider;
47 private final TextView mLabel;
48 private final H mHandler = new H();
49
50 private boolean mDual;
51 private OnClickListener mClickPrimary;
52 private OnClickListener mClickSecondary;
53
54 public QSTileView(Context context) {
55 super(context);
56
57 mContext = context;
58 final Resources res = context.getResources();
59 mLabel = new TextView(mContext);
60 mLabel.setId(android.R.id.title);
61 mLabel.setTextColor(res.getColor(R.color.quick_settings_tile_text));
62 mLabel.setGravity(Gravity.CENTER);
63 mLabel.setTypeface(CONDENSED);
64 mLabel.setTextSize(TypedValue.COMPLEX_UNIT_PX,
65 res.getDimensionPixelSize(R.dimen.quick_settings_tile_text_size));
66 addView(mLabel);
67 setClipChildren(false);
68
69 mIcon = createIcon();
70 addView(mIcon);
71
72 mDivider = new View(mContext);
73 mDivider.setBackgroundColor(res.getColor(R.color.quick_settings_tile_divider));
74 final int dh = res.getDimensionPixelSize(R.dimen.quick_settings_tile_divider_height);
75 mDivider.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, dh));
76 addView(mDivider);
77
78 setClickable(true);
79 setBackground(getSelectableBackground());
80 }
81
82 public void setDual(boolean dual) {
83 mDual = dual;
84 if (mDual) {
85 setOnClickListener(mClickPrimary);
86 mLabel.setClickable(true);
87 mLabel.setOnClickListener(mClickSecondary);
88 } else {
89 mLabel.setClickable(false);
90 setOnClickListener(mClickPrimary);
91 }
92 mDivider.setVisibility(dual ? VISIBLE : GONE);
93 postInvalidate();
94 }
95
96 public void init(OnClickListener clickPrimary, OnClickListener clickSecondary) {
97 mClickPrimary = clickPrimary;
98 mClickSecondary = clickSecondary;
99 }
100
101 protected View createIcon() {
John Spurlock83e28482014-05-18 17:20:05 -0400102 final ImageView icon = new ImageView(mContext);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400103 icon.setId(android.R.id.icon);
104 icon.setScaleType(ScaleType.CENTER_INSIDE);
105 return icon;
106 }
107
108 private Drawable getSelectableBackground() {
109 final int[] attrs = new int[] { android.R.attr.selectableItemBackground};
110 final TypedArray ta = mContext.obtainStyledAttributes(attrs);
111 final Drawable d = ta.getDrawable(0);
112 ta.recycle();
113 return d;
114 }
115
116 @Override
117 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
118 final int w = MeasureSpec.getSize(widthMeasureSpec);
119 final int h = MeasureSpec.getSize(heightMeasureSpec);
120 final int p = h / VERTICAL_PADDING_FACTOR;
121 final int iconSpec = exactly((int)mLabel.getTextSize() * 2);
122 mIcon.measure(iconSpec, iconSpec);
123 mLabel.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(h, MeasureSpec.AT_MOST));
124 mLabel.measure(widthMeasureSpec, exactly(mLabel.getMeasuredHeight() + p * 2));
125 if (mDual) {
126 mDivider.measure(widthMeasureSpec, exactly(mDivider.getLayoutParams().height));
127 }
128 setMeasuredDimension(w, h);
129 }
130
131 private static int exactly(int size) {
132 return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
133 }
134
135 @Override
136 protected void onLayout(boolean changed, int l, int t, int r, int b) {
137 final int w = getMeasuredWidth();
138 final int h = getMeasuredHeight();
139 final int p = h / VERTICAL_PADDING_FACTOR;
140 final int contentHeight = p + mIcon.getMeasuredHeight() + mLabel.getMeasuredHeight()
141 + (mDual ? (p + mDivider.getMeasuredHeight()) : 0);
142
143 int top = (h - contentHeight) / 2 + p;
144 final int iconLeft = (w - mIcon.getMeasuredWidth()) / 2;
145 layout(mIcon, iconLeft, top);
146 top = mIcon.getBottom();
147 if (mDual) {
148 top += p;
149 layout(mDivider, 0, top);
150 top = mDivider.getBottom();
151 }
152 layout(mLabel, 0, top);
153 }
154
155 private static void layout(View child, int left, int top) {
156 child.layout(left, top, left + child.getMeasuredWidth(), top + child.getMeasuredHeight());
157 }
158
159 protected void handleStateChanged(QSTile.State state) {
John Spurlock83e28482014-05-18 17:20:05 -0400160 if (mIcon instanceof ImageView) {
161 ImageView iv = (ImageView) mIcon;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400162 if (state.icon != null) {
John Spurlock83e28482014-05-18 17:20:05 -0400163 iv.setImageDrawable(state.icon);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400164 } else if (state.iconId > 0) {
John Spurlock83e28482014-05-18 17:20:05 -0400165 iv.setImageResource(state.iconId);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400166 }
167 }
168 mLabel.setText(state.label);
169 setContentDescription(state.contentDescription);
170 }
171
172 public void onStateChanged(QSTile.State state) {
173 mHandler.obtainMessage(H.STATE_CHANGED, state).sendToTarget();
174 }
175
176 private class H extends Handler {
177 private static final int STATE_CHANGED = 1;
178 public H() {
179 super(Looper.getMainLooper());
180 }
181 @Override
182 public void handleMessage(Message msg) {
183 if (msg.what == STATE_CHANGED) {
184 handleStateChanged((State) msg.obj);
185 }
186 }
187 }
188}