1d9c68b37dc97e5a197896c88a1f1cd3d360234d
[pub/Android/ownCloud.git] / actionbarsherlock / src / com / actionbarsherlock / internal / widget / ActionBarContainer.java
1 /*
2 * Copyright (C) 2010 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.actionbarsherlock.internal.widget;
18
19 import android.content.Context;
20 import android.content.res.TypedArray;
21 import android.graphics.Bitmap;
22 import android.graphics.Canvas;
23 import android.graphics.drawable.ColorDrawable;
24 import android.graphics.drawable.Drawable;
25 import android.os.Build;
26 import android.util.AttributeSet;
27 import android.view.MotionEvent;
28 import android.view.View;
29 import android.view.ViewGroup;
30
31 import com.actionbarsherlock.R;
32 import com.actionbarsherlock.app.ActionBar;
33 import com.actionbarsherlock.internal.nineoldandroids.widget.NineFrameLayout;
34
35 /**
36 * This class acts as a container for the action bar view and action mode context views.
37 * It applies special styles as needed to help handle animated transitions between them.
38 * @hide
39 */
40 public class ActionBarContainer extends NineFrameLayout {
41 private boolean mIsTransitioning;
42 private View mTabContainer;
43 private ActionBarView mActionBarView;
44
45 private Drawable mBackground;
46 private Drawable mStackedBackground;
47 private Drawable mSplitBackground;
48 private boolean mIsSplit;
49 private boolean mIsStacked;
50
51 public ActionBarContainer(Context context) {
52 this(context, null);
53 }
54
55 public ActionBarContainer(Context context, AttributeSet attrs) {
56 super(context, attrs);
57
58 setBackgroundDrawable(null);
59
60 TypedArray a = context.obtainStyledAttributes(attrs,
61 R.styleable.SherlockActionBar);
62 mBackground = a.getDrawable(R.styleable.SherlockActionBar_background);
63 mStackedBackground = a.getDrawable(
64 R.styleable.SherlockActionBar_backgroundStacked);
65
66 //Fix for issue #379
67 if (mStackedBackground instanceof ColorDrawable && Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
68 Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
69 Canvas c = new Canvas(bitmap);
70 mStackedBackground.draw(c);
71 int color = bitmap.getPixel(0, 0);
72 bitmap.recycle();
73 mStackedBackground = new IcsColorDrawable(color);
74 }
75
76 if (getId() == R.id.abs__split_action_bar) {
77 mIsSplit = true;
78 mSplitBackground = a.getDrawable(
79 R.styleable.SherlockActionBar_backgroundSplit);
80 }
81 a.recycle();
82
83 setWillNotDraw(mIsSplit ? mSplitBackground == null :
84 mBackground == null && mStackedBackground == null);
85 }
86
87 @Override
88 public void onFinishInflate() {
89 super.onFinishInflate();
90 mActionBarView = (ActionBarView) findViewById(R.id.abs__action_bar);
91 }
92
93 public void setPrimaryBackground(Drawable bg) {
94 mBackground = bg;
95 invalidate();
96 }
97
98 public void setStackedBackground(Drawable bg) {
99 mStackedBackground = bg;
100 invalidate();
101 }
102
103 public void setSplitBackground(Drawable bg) {
104 mSplitBackground = bg;
105 invalidate();
106 }
107
108 /**
109 * Set the action bar into a "transitioning" state. While transitioning
110 * the bar will block focus and touch from all of its descendants. This
111 * prevents the user from interacting with the bar while it is animating
112 * in or out.
113 *
114 * @param isTransitioning true if the bar is currently transitioning, false otherwise.
115 */
116 public void setTransitioning(boolean isTransitioning) {
117 mIsTransitioning = isTransitioning;
118 setDescendantFocusability(isTransitioning ? FOCUS_BLOCK_DESCENDANTS
119 : FOCUS_AFTER_DESCENDANTS);
120 }
121
122 @Override
123 public boolean onInterceptTouchEvent(MotionEvent ev) {
124 return mIsTransitioning || super.onInterceptTouchEvent(ev);
125 }
126
127 @Override
128 public boolean onTouchEvent(MotionEvent ev) {
129 super.onTouchEvent(ev);
130
131 // An action bar always eats touch events.
132 return true;
133 }
134
135 @Override
136 public boolean onHoverEvent(MotionEvent ev) {
137 super.onHoverEvent(ev);
138
139 // An action bar always eats hover events.
140 return true;
141 }
142
143 public void setTabContainer(ScrollingTabContainerView tabView) {
144 if (mTabContainer != null) {
145 removeView(mTabContainer);
146 }
147 mTabContainer = tabView;
148 if (tabView != null) {
149 addView(tabView);
150 final ViewGroup.LayoutParams lp = tabView.getLayoutParams();
151 lp.width = LayoutParams.MATCH_PARENT;
152 lp.height = LayoutParams.WRAP_CONTENT;
153 tabView.setAllowCollapse(false);
154 }
155 }
156
157 public View getTabContainer() {
158 return mTabContainer;
159 }
160
161 @Override
162 public void onDraw(Canvas canvas) {
163 if (getWidth() == 0 || getHeight() == 0) {
164 return;
165 }
166
167 if (mIsSplit) {
168 if (mSplitBackground != null) mSplitBackground.draw(canvas);
169 } else {
170 if (mBackground != null) {
171 mBackground.draw(canvas);
172 }
173 if (mStackedBackground != null && mIsStacked) {
174 mStackedBackground.draw(canvas);
175 }
176 }
177 }
178
179 //This causes the animation reflection to fail on pre-HC platforms
180 //@Override
181 //public android.view.ActionMode startActionModeForChild(View child, android.view.ActionMode.Callback callback) {
182 // // No starting an action mode for an action bar child! (Where would it go?)
183 // return null;
184 //}
185
186 @Override
187 public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
188 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
189
190 if (mActionBarView == null) return;
191
192 final LayoutParams lp = (LayoutParams) mActionBarView.getLayoutParams();
193 final int actionBarViewHeight = mActionBarView.isCollapsed() ? 0 :
194 mActionBarView.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
195
196 if (mTabContainer != null && mTabContainer.getVisibility() != GONE) {
197 final int mode = MeasureSpec.getMode(heightMeasureSpec);
198 if (mode == MeasureSpec.AT_MOST) {
199 final int maxHeight = MeasureSpec.getSize(heightMeasureSpec);
200 setMeasuredDimension(getMeasuredWidth(),
201 Math.min(actionBarViewHeight + mTabContainer.getMeasuredHeight(),
202 maxHeight));
203 }
204 }
205 }
206
207 @Override
208 public void onLayout(boolean changed, int l, int t, int r, int b) {
209 super.onLayout(changed, l, t, r, b);
210
211 final boolean hasTabs = mTabContainer != null && mTabContainer.getVisibility() != GONE;
212
213 if (mTabContainer != null && mTabContainer.getVisibility() != GONE) {
214 final int containerHeight = getMeasuredHeight();
215 final int tabHeight = mTabContainer.getMeasuredHeight();
216
217 if ((mActionBarView.getDisplayOptions() & ActionBar.DISPLAY_SHOW_HOME) == 0) {
218 // Not showing home, put tabs on top.
219 final int count = getChildCount();
220 for (int i = 0; i < count; i++) {
221 final View child = getChildAt(i);
222
223 if (child == mTabContainer) continue;
224
225 if (!mActionBarView.isCollapsed()) {
226 child.offsetTopAndBottom(tabHeight);
227 }
228 }
229 mTabContainer.layout(l, 0, r, tabHeight);
230 } else {
231 mTabContainer.layout(l, containerHeight - tabHeight, r, containerHeight);
232 }
233 }
234
235 boolean needsInvalidate = false;
236 if (mIsSplit) {
237 if (mSplitBackground != null) {
238 mSplitBackground.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
239 needsInvalidate = true;
240 }
241 } else {
242 if (mBackground != null) {
243 mBackground.setBounds(mActionBarView.getLeft(), mActionBarView.getTop(),
244 mActionBarView.getRight(), mActionBarView.getBottom());
245 needsInvalidate = true;
246 }
247 if ((mIsStacked = hasTabs && mStackedBackground != null)) {
248 mStackedBackground.setBounds(mTabContainer.getLeft(), mTabContainer.getTop(),
249 mTabContainer.getRight(), mTabContainer.getBottom());
250 needsInvalidate = true;
251 }
252 }
253
254 if (needsInvalidate) {
255 invalidate();
256 }
257 }
258 }