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 17package com.android.systemui.statusbar; 18 19import android.content.Context; 20import android.os.Handler; 21import android.util.AttributeSet; 22import android.util.Slog; 23import android.view.View; 24import android.widget.LinearLayout; 25 26import com.android.internal.statusbar.StatusBarIcon; 27 28import com.android.systemui.R; 29 30 31public class IconMerger extends LinearLayout { 32 private static final String TAG = "IconMerger"; 33 34 private int mIconSize; 35 private StatusBarIconView mMoreView; 36 private StatusBarIcon mMoreIcon = new StatusBarIcon(null, R.drawable.stat_notify_more, 0); 37 38 public IconMerger(Context context, AttributeSet attrs) { 39 super(context, attrs); 40 41 mIconSize = context.getResources().getDimensionPixelSize( 42 com.android.internal.R.dimen.status_bar_icon_size); 43 44 mMoreView = new StatusBarIconView(context, "more"); 45 mMoreView.set(mMoreIcon); 46 addView(mMoreView, 0, new LinearLayout.LayoutParams(mIconSize, mIconSize)); 47 } 48 49 public void addView(StatusBarIconView v, int index) { 50 if (index == 0) { 51 throw new RuntimeException("Attempt to put view before the more view: " + v); 52 } 53 addView(v, index, new LinearLayout.LayoutParams(mIconSize, mIconSize)); 54 } 55 56 @Override 57 protected void onLayout(boolean changed, int l, int t, int r, int b) { 58 super.onLayout(changed, l, t, r, b); 59 60 final int maxWidth = r - l; 61 final int N = getChildCount(); 62 int i; 63 64 // get the rightmost one, and see if we even need to do anything 65 int fitRight = -1; 66 for (i=N-1; i>=0; i--) { 67 final View child = getChildAt(i); 68 if (child.getVisibility() != GONE) { 69 fitRight = child.getRight(); 70 break; 71 } 72 } 73 74 // find the first visible one that isn't the more icon 75 final StatusBarIconView moreView = mMoreView; 76 int fitLeft = -1; 77 int startIndex = -1; 78 for (i=0; i<N; i++) { 79 final View child = getChildAt(i); 80 if (child == moreView) { 81 startIndex = i+1; 82 } 83 else if (child.getVisibility() != GONE) { 84 fitLeft = child.getLeft(); 85 break; 86 } 87 } 88 89 if (moreView == null || startIndex < 0) { 90 return; 91 /* 92 throw new RuntimeException("Status Bar / IconMerger moreView == " + moreView 93 + " startIndex=" + startIndex); 94 */ 95 } 96 97 // if it fits without the more icon, then hide the more icon and update fitLeft 98 // so everything gets pushed left 99 int adjust = 0; 100 if (fitRight - fitLeft <= maxWidth) { 101 adjust = fitLeft - moreView.getLeft(); 102 fitLeft -= adjust; 103 fitRight -= adjust; 104 moreView.layout(0, moreView.getTop(), 0, moreView.getBottom()); 105 } 106 int extra = fitRight - r; 107 int shift = -1; 108 109 int breakingPoint = fitLeft + extra + adjust; 110 int number = 0; 111 for (i=startIndex; i<N; i++) { 112 final StatusBarIconView child = (StatusBarIconView)getChildAt(i); 113 if (child.getVisibility() != GONE) { 114 int childLeft = child.getLeft(); 115 int childRight = child.getRight(); 116 if (childLeft < breakingPoint) { 117 // hide this one 118 child.layout(0, child.getTop(), 0, child.getBottom()); 119 int n = child.getStatusBarIcon().number; 120 if (n == 0) { 121 number += 1; 122 } else if (n > 0) { 123 number += n; 124 } 125 } else { 126 // decide how much to shift by 127 if (shift < 0) { 128 shift = childLeft - fitLeft; 129 } 130 // shift this left by shift 131 child.layout(childLeft-shift, child.getTop(), 132 childRight-shift, child.getBottom()); 133 } 134 } 135 } 136 137 mMoreIcon.number = number; 138 mMoreView.set(mMoreIcon); 139 } 140} 141