blob: 340a4d5df820f5ce0962a6111b5d78eae6ace58d [file] [log] [blame]
Jim Miller19a52672012-10-23 19:52:04 -07001/*
2 * Copyright (C) 2012 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
Jim Miller5ecd8112013-01-09 18:50:26 -080017package com.android.keyguard;
Adam Powell9d34f9d2012-11-06 15:25:05 -080018
Chris Wrenc3451462012-10-30 11:22:58 -040019import android.animation.Animator;
Chris Wrenc3451462012-10-30 11:22:58 -040020import android.animation.AnimatorListenerAdapter;
21import android.animation.ObjectAnimator;
Jim Miller19a52672012-10-23 19:52:04 -070022import android.content.Context;
Adam Powell9d34f9d2012-11-06 15:25:05 -080023import android.content.res.Resources;
Jim Miller19a52672012-10-23 19:52:04 -070024import android.content.res.TypedArray;
25import android.graphics.Rect;
26import android.util.AttributeSet;
Adam Powell9d34f9d2012-11-06 15:25:05 -080027import android.util.DisplayMetrics;
Jim Miller19a52672012-10-23 19:52:04 -070028import android.view.Gravity;
29import android.view.View;
30import android.view.ViewGroup;
31import android.widget.LinearLayout;
32
Jim Miller19a52672012-10-23 19:52:04 -070033public class MultiPaneChallengeLayout extends ViewGroup implements ChallengeLayout {
34 private static final String TAG = "MultiPaneChallengeLayout";
35
36 final int mOrientation;
Adam Powelleee20932012-10-24 16:26:56 -070037 private boolean mIsBouncing;
Jim Miller19a52672012-10-23 19:52:04 -070038
39 public static final int HORIZONTAL = LinearLayout.HORIZONTAL;
40 public static final int VERTICAL = LinearLayout.VERTICAL;
Winson Chung70c2f872012-11-07 21:47:12 -080041 public static final int ANIMATE_BOUNCE_DURATION = 350;
Jim Miller19a52672012-10-23 19:52:04 -070042
Chris Wrenc3451462012-10-30 11:22:58 -040043 private KeyguardSecurityContainer mChallengeView;
Jim Miller19a52672012-10-23 19:52:04 -070044 private View mUserSwitcherView;
Adam Powelleee20932012-10-24 16:26:56 -070045 private View mScrimView;
Adam Powell0b1b5522012-10-25 13:39:30 -070046 private OnBouncerStateChangedListener mBouncerListener;
Jim Miller19a52672012-10-23 19:52:04 -070047
48 private final Rect mTempRect = new Rect();
Winson Chungc065a5d2012-11-07 17:17:33 -080049 private final Rect mZeroPadding = new Rect();
John Spurlock256ae672013-09-26 12:14:33 -040050 private final Rect mInsets = new Rect();
Adam Powell9d34f9d2012-11-06 15:25:05 -080051
52 private final DisplayMetrics mDisplayMetrics;
Jim Miller19a52672012-10-23 19:52:04 -070053
Adam Powelleee20932012-10-24 16:26:56 -070054 private final OnClickListener mScrimClickListener = new OnClickListener() {
55 @Override
56 public void onClick(View v) {
57 hideBouncer();
58 }
59 };
60
Jim Miller19a52672012-10-23 19:52:04 -070061 public MultiPaneChallengeLayout(Context context) {
62 this(context, null);
63 }
64
65 public MultiPaneChallengeLayout(Context context, AttributeSet attrs) {
66 this(context, attrs, 0);
67 }
68
69 public MultiPaneChallengeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
70 super(context, attrs, defStyleAttr);
71
72 final TypedArray a = context.obtainStyledAttributes(attrs,
73 R.styleable.MultiPaneChallengeLayout, defStyleAttr, 0);
Jim Miller5ecd8112013-01-09 18:50:26 -080074 mOrientation = a.getInt(R.styleable.MultiPaneChallengeLayout_android_orientation,
Jim Miller19a52672012-10-23 19:52:04 -070075 HORIZONTAL);
76 a.recycle();
Adam Powell9d34f9d2012-11-06 15:25:05 -080077
78 final Resources res = getResources();
79 mDisplayMetrics = res.getDisplayMetrics();
Adam Powelleec4fe22012-11-07 18:07:15 -080080
John Spurlockbd957402013-10-03 11:38:39 -040081 setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_STABLE | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
Jim Miller19a52672012-10-23 19:52:04 -070082 }
83
John Spurlock256ae672013-09-26 12:14:33 -040084 public void setInsets(Rect insets) {
85 mInsets.set(insets);
86 }
87
Jim Miller19a52672012-10-23 19:52:04 -070088 @Override
89 public boolean isChallengeShowing() {
90 return true;
91 }
92
93 @Override
94 public boolean isChallengeOverlapping() {
95 return false;
96 }
97
98 @Override
99 public void showChallenge(boolean b) {
100 }
101
102 @Override
Winson Chung70c2f872012-11-07 21:47:12 -0800103 public int getBouncerAnimationDuration() {
104 return ANIMATE_BOUNCE_DURATION;
105 }
106
107 @Override
Jim Miller19a52672012-10-23 19:52:04 -0700108 public void showBouncer() {
Adam Powelleee20932012-10-24 16:26:56 -0700109 if (mIsBouncing) return;
110 mIsBouncing = true;
111 if (mScrimView != null) {
Chris Wrenc3451462012-10-30 11:22:58 -0400112 if (mChallengeView != null) {
113 mChallengeView.showBouncer(ANIMATE_BOUNCE_DURATION);
114 }
115
116 Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 1f);
117 anim.setDuration(ANIMATE_BOUNCE_DURATION);
118 anim.addListener(new AnimatorListenerAdapter() {
119 @Override
120 public void onAnimationStart(Animator animation) {
121 mScrimView.setVisibility(VISIBLE);
122 }
123 });
124 anim.start();
Adam Powelleee20932012-10-24 16:26:56 -0700125 }
Adam Powell0b1b5522012-10-25 13:39:30 -0700126 if (mBouncerListener != null) {
127 mBouncerListener.onBouncerStateChanged(true);
128 }
Adam Powelleee20932012-10-24 16:26:56 -0700129 }
130
131 @Override
132 public void hideBouncer() {
133 if (!mIsBouncing) return;
134 mIsBouncing = false;
135 if (mScrimView != null) {
Chris Wrenc3451462012-10-30 11:22:58 -0400136 if (mChallengeView != null) {
137 mChallengeView.hideBouncer(ANIMATE_BOUNCE_DURATION);
138 }
139
140 Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 0f);
141 anim.setDuration(ANIMATE_BOUNCE_DURATION);
142 anim.addListener(new AnimatorListenerAdapter() {
143 @Override
144 public void onAnimationEnd(Animator animation) {
145 mScrimView.setVisibility(INVISIBLE);
146 }
147 });
148 anim.start();
Adam Powelleee20932012-10-24 16:26:56 -0700149 }
Adam Powell0b1b5522012-10-25 13:39:30 -0700150 if (mBouncerListener != null) {
151 mBouncerListener.onBouncerStateChanged(false);
152 }
Adam Powelleee20932012-10-24 16:26:56 -0700153 }
154
155 @Override
156 public boolean isBouncing() {
157 return mIsBouncing;
158 }
159
Adam Powell0b1b5522012-10-25 13:39:30 -0700160 @Override
161 public void setOnBouncerStateChangedListener(OnBouncerStateChangedListener listener) {
162 mBouncerListener = listener;
163 }
164
165 @Override
166 public void requestChildFocus(View child, View focused) {
167 if (mIsBouncing && child != mChallengeView) {
168 // Clear out of the bouncer if the user tries to move focus outside of
169 // the security challenge view.
170 hideBouncer();
171 }
172 super.requestChildFocus(child, focused);
173 }
174
Adam Powelleee20932012-10-24 16:26:56 -0700175 void setScrimView(View scrim) {
176 if (mScrimView != null) {
177 mScrimView.setOnClickListener(null);
178 }
179 mScrimView = scrim;
John Spurlock257f2832013-09-21 18:41:53 -0400180 if (mScrimView != null) {
181 mScrimView.setAlpha(mIsBouncing ? 1.0f : 0.0f);
182 mScrimView.setVisibility(mIsBouncing ? VISIBLE : INVISIBLE);
183 mScrimView.setFocusable(true);
184 mScrimView.setOnClickListener(mScrimClickListener);
185 }
Jim Miller19a52672012-10-23 19:52:04 -0700186 }
187
Adam Powell9d34f9d2012-11-06 15:25:05 -0800188 private int getVirtualHeight(LayoutParams lp, int height, int heightUsed) {
189 int virtualHeight = height;
190 final View root = getRootView();
191 if (root != null) {
192 // This calculation is super dodgy and relies on several assumptions.
193 // Specifically that the root of the window will be padded in for insets
194 // and that the window is LAYOUT_IN_SCREEN.
John Spurlock256ae672013-09-26 12:14:33 -0400195 virtualHeight = mDisplayMetrics.heightPixels - root.getPaddingTop() - mInsets.top;
Adam Powell9d34f9d2012-11-06 15:25:05 -0800196 }
Alan Viverette0cec85b2013-10-10 17:46:03 -0700197 if (lp.childType == LayoutParams.CHILD_TYPE_USER_SWITCHER) {
198 // Always measure the user switcher as if there were no IME insets
199 // on the window.
Adam Powell9d34f9d2012-11-06 15:25:05 -0800200 return virtualHeight - heightUsed;
Winson Chungc065a5d2012-11-07 17:17:33 -0800201 } else if (lp.childType == LayoutParams.CHILD_TYPE_PAGE_DELETE_DROP_TARGET) {
202 return height;
Adam Powell9d34f9d2012-11-06 15:25:05 -0800203 }
204 return Math.min(virtualHeight - heightUsed, height);
205 }
206
Jim Miller19a52672012-10-23 19:52:04 -0700207 @Override
Adam Powell9d34f9d2012-11-06 15:25:05 -0800208 protected void onMeasure(final int widthSpec, final int heightSpec) {
Jim Miller19a52672012-10-23 19:52:04 -0700209 if (MeasureSpec.getMode(widthSpec) != MeasureSpec.EXACTLY ||
210 MeasureSpec.getMode(heightSpec) != MeasureSpec.EXACTLY) {
211 throw new IllegalArgumentException(
212 "MultiPaneChallengeLayout must be measured with an exact size");
213 }
214
215 final int width = MeasureSpec.getSize(widthSpec);
216 final int height = MeasureSpec.getSize(heightSpec);
217 setMeasuredDimension(width, height);
218
John Spurlock256ae672013-09-26 12:14:33 -0400219 final int insetHeight = height - mInsets.top - mInsets.bottom;
220 final int insetHeightSpec = MeasureSpec.makeMeasureSpec(insetHeight, MeasureSpec.EXACTLY);
221
Jim Miller19a52672012-10-23 19:52:04 -0700222 int widthUsed = 0;
223 int heightUsed = 0;
224
225 // First pass. Find the challenge view and measure the user switcher,
226 // which consumes space in the layout.
227 mChallengeView = null;
228 mUserSwitcherView = null;
229 final int count = getChildCount();
230 for (int i = 0; i < count; i++) {
231 final View child = getChildAt(i);
232 final LayoutParams lp = (LayoutParams) child.getLayoutParams();
233
234 if (lp.childType == LayoutParams.CHILD_TYPE_CHALLENGE) {
235 if (mChallengeView != null) {
236 throw new IllegalStateException(
237 "There may only be one child of type challenge");
238 }
Chris Wrenc3451462012-10-30 11:22:58 -0400239 if (!(child instanceof KeyguardSecurityContainer)) {
240 throw new IllegalArgumentException(
241 "Challenge must be a KeyguardSecurityContainer");
242 }
243 mChallengeView = (KeyguardSecurityContainer) child;
Jim Miller19a52672012-10-23 19:52:04 -0700244 } else if (lp.childType == LayoutParams.CHILD_TYPE_USER_SWITCHER) {
245 if (mUserSwitcherView != null) {
246 throw new IllegalStateException(
247 "There may only be one child of type userSwitcher");
248 }
249 mUserSwitcherView = child;
250
251 if (child.getVisibility() == GONE) continue;
252
Adam Powell9d34f9d2012-11-06 15:25:05 -0800253 int adjustedWidthSpec = widthSpec;
John Spurlock256ae672013-09-26 12:14:33 -0400254 int adjustedHeightSpec = insetHeightSpec;
Adam Powell9d34f9d2012-11-06 15:25:05 -0800255 if (lp.maxWidth >= 0) {
256 adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
257 Math.min(lp.maxWidth, width), MeasureSpec.EXACTLY);
258 }
259 if (lp.maxHeight >= 0) {
260 adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
John Spurlock256ae672013-09-26 12:14:33 -0400261 Math.min(lp.maxHeight, insetHeight), MeasureSpec.EXACTLY);
Adam Powell9d34f9d2012-11-06 15:25:05 -0800262 }
263 // measureChildWithMargins will resolve layout direction for the LayoutParams
264 measureChildWithMargins(child, adjustedWidthSpec, 0, adjustedHeightSpec, 0);
265
266 // Only subtract out space from one dimension. Favor vertical.
267 // Offset by 1.5x to add some balance along the other edge.
268 if (Gravity.isVertical(lp.gravity)) {
269 heightUsed += child.getMeasuredHeight() * 1.5f;
270 } else if (Gravity.isHorizontal(lp.gravity)) {
271 widthUsed += child.getMeasuredWidth() * 1.5f;
Jim Miller19a52672012-10-23 19:52:04 -0700272 }
Adam Powelleee20932012-10-24 16:26:56 -0700273 } else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) {
274 setScrimView(child);
275 child.measure(widthSpec, heightSpec);
Jim Miller19a52672012-10-23 19:52:04 -0700276 }
277 }
278
279 // Second pass. Measure everything that's left.
280 for (int i = 0; i < count; i++) {
281 final View child = getChildAt(i);
282 final LayoutParams lp = (LayoutParams) child.getLayoutParams();
283
284 if (lp.childType == LayoutParams.CHILD_TYPE_USER_SWITCHER ||
Adam Powelleee20932012-10-24 16:26:56 -0700285 lp.childType == LayoutParams.CHILD_TYPE_SCRIM ||
Jim Miller19a52672012-10-23 19:52:04 -0700286 child.getVisibility() == GONE) {
287 // Don't need to measure GONE children, and the user switcher was already measured.
288 continue;
289 }
290
John Spurlock256ae672013-09-26 12:14:33 -0400291 final int virtualHeight = getVirtualHeight(lp, insetHeight, heightUsed);
Adam Powell9d34f9d2012-11-06 15:25:05 -0800292
Jim Miller19a52672012-10-23 19:52:04 -0700293 int adjustedWidthSpec;
294 int adjustedHeightSpec;
295 if (lp.centerWithinArea > 0) {
296 if (mOrientation == HORIZONTAL) {
297 adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
Adam Powell0a27c482012-10-26 17:00:52 -0700298 (int) ((width - widthUsed) * lp.centerWithinArea + 0.5f),
299 MeasureSpec.EXACTLY);
Jim Miller19a52672012-10-23 19:52:04 -0700300 adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
Adam Powell9d34f9d2012-11-06 15:25:05 -0800301 virtualHeight, MeasureSpec.EXACTLY);
Adam Powell0a27c482012-10-26 17:00:52 -0700302 } else {
303 adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
Adam Powell9d34f9d2012-11-06 15:25:05 -0800304 width - widthUsed, MeasureSpec.EXACTLY);
Adam Powell0a27c482012-10-26 17:00:52 -0700305 adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
Adam Powell9d34f9d2012-11-06 15:25:05 -0800306 (int) (virtualHeight * lp.centerWithinArea + 0.5f),
Adam Powell0a27c482012-10-26 17:00:52 -0700307 MeasureSpec.EXACTLY);
Jim Miller19a52672012-10-23 19:52:04 -0700308 }
309 } else {
Adam Powell0a27c482012-10-26 17:00:52 -0700310 adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
Adam Powell9d34f9d2012-11-06 15:25:05 -0800311 width - widthUsed, MeasureSpec.EXACTLY);
Adam Powell0a27c482012-10-26 17:00:52 -0700312 adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
Adam Powell9d34f9d2012-11-06 15:25:05 -0800313 virtualHeight, MeasureSpec.EXACTLY);
Jim Miller19a52672012-10-23 19:52:04 -0700314 }
315 if (lp.maxWidth >= 0) {
316 adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
Adam Powell0a27c482012-10-26 17:00:52 -0700317 Math.min(lp.maxWidth, MeasureSpec.getSize(adjustedWidthSpec)),
Jim Miller19a52672012-10-23 19:52:04 -0700318 MeasureSpec.EXACTLY);
319 }
320 if (lp.maxHeight >= 0) {
321 adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
Adam Powell0a27c482012-10-26 17:00:52 -0700322 Math.min(lp.maxHeight, MeasureSpec.getSize(adjustedHeightSpec)),
Jim Miller19a52672012-10-23 19:52:04 -0700323 MeasureSpec.EXACTLY);
324 }
325
Adam Powell0a27c482012-10-26 17:00:52 -0700326 measureChildWithMargins(child, adjustedWidthSpec, 0, adjustedHeightSpec, 0);
Jim Miller19a52672012-10-23 19:52:04 -0700327 }
328 }
329
330 @Override
331 protected void onLayout(boolean changed, int l, int t, int r, int b) {
332 final Rect padding = mTempRect;
333 padding.left = getPaddingLeft();
334 padding.top = getPaddingTop();
335 padding.right = getPaddingRight();
336 padding.bottom = getPaddingBottom();
337 final int width = r - l;
338 final int height = b - t;
John Spurlock256ae672013-09-26 12:14:33 -0400339 final int insetHeight = height - mInsets.top - mInsets.bottom;
Jim Miller19a52672012-10-23 19:52:04 -0700340
341 // Reserve extra space in layout for the user switcher by modifying
342 // local padding during this layout pass
343 if (mUserSwitcherView != null && mUserSwitcherView.getVisibility() != GONE) {
John Spurlock256ae672013-09-26 12:14:33 -0400344 layoutWithGravity(width, insetHeight, mUserSwitcherView, padding, true);
Jim Miller19a52672012-10-23 19:52:04 -0700345 }
346
347 final int count = getChildCount();
348 for (int i = 0; i < count; i++) {
349 final View child = getChildAt(i);
Winson Chungc065a5d2012-11-07 17:17:33 -0800350 LayoutParams lp = (LayoutParams) child.getLayoutParams();
Jim Miller19a52672012-10-23 19:52:04 -0700351
352 // We did the user switcher above if we have one.
353 if (child == mUserSwitcherView || child.getVisibility() == GONE) continue;
354
Adam Powelleee20932012-10-24 16:26:56 -0700355 if (child == mScrimView) {
356 child.layout(0, 0, width, height);
357 continue;
Winson Chungc065a5d2012-11-07 17:17:33 -0800358 } else if (lp.childType == LayoutParams.CHILD_TYPE_PAGE_DELETE_DROP_TARGET) {
John Spurlock256ae672013-09-26 12:14:33 -0400359 layoutWithGravity(width, insetHeight, child, mZeroPadding, false);
Winson Chungc065a5d2012-11-07 17:17:33 -0800360 continue;
Adam Powelleee20932012-10-24 16:26:56 -0700361 }
362
John Spurlock256ae672013-09-26 12:14:33 -0400363 layoutWithGravity(width, insetHeight, child, padding, false);
Jim Miller19a52672012-10-23 19:52:04 -0700364 }
365 }
366
367 private void layoutWithGravity(int width, int height, View child, Rect padding,
368 boolean adjustPadding) {
369 final LayoutParams lp = (LayoutParams) child.getLayoutParams();
370
Adam Powell9d34f9d2012-11-06 15:25:05 -0800371 final int heightUsed = padding.top + padding.bottom - getPaddingTop() - getPaddingBottom();
372 height = getVirtualHeight(lp, height, heightUsed);
373
Jim Miller19a52672012-10-23 19:52:04 -0700374 final int gravity = Gravity.getAbsoluteGravity(lp.gravity, getLayoutDirection());
375
376 final boolean fixedLayoutSize = lp.centerWithinArea > 0;
377 final boolean fixedLayoutHorizontal = fixedLayoutSize && mOrientation == HORIZONTAL;
378 final boolean fixedLayoutVertical = fixedLayoutSize && mOrientation == VERTICAL;
379
380 final int adjustedWidth;
381 final int adjustedHeight;
382 if (fixedLayoutHorizontal) {
Adam Powellc0657fb2012-10-24 14:00:04 -0700383 final int paddedWidth = width - padding.left - padding.right;
384 adjustedWidth = (int) (paddedWidth * lp.centerWithinArea + 0.5f);
Jim Miller19a52672012-10-23 19:52:04 -0700385 adjustedHeight = height;
386 } else if (fixedLayoutVertical) {
Adam Powelleeb62552012-11-07 14:07:23 -0800387 final int paddedHeight = height - getPaddingTop() - getPaddingBottom();
Jim Miller19a52672012-10-23 19:52:04 -0700388 adjustedWidth = width;
Adam Powellc0657fb2012-10-24 14:00:04 -0700389 adjustedHeight = (int) (paddedHeight * lp.centerWithinArea + 0.5f);
Jim Miller19a52672012-10-23 19:52:04 -0700390 } else {
391 adjustedWidth = width;
392 adjustedHeight = height;
393 }
394
395 final boolean isVertical = Gravity.isVertical(gravity);
396 final boolean isHorizontal = Gravity.isHorizontal(gravity);
397 final int childWidth = child.getMeasuredWidth();
398 final int childHeight = child.getMeasuredHeight();
399
400 int left = padding.left;
401 int top = padding.top;
402 int right = left + childWidth;
403 int bottom = top + childHeight;
404 switch (gravity & Gravity.VERTICAL_GRAVITY_MASK) {
405 case Gravity.TOP:
406 top = fixedLayoutVertical ?
407 padding.top + (adjustedHeight - childHeight) / 2 : padding.top;
408 bottom = top + childHeight;
Adam Powellc0657fb2012-10-24 14:00:04 -0700409 if (adjustPadding && isVertical) {
410 padding.top = bottom;
411 padding.bottom += childHeight / 2;
412 }
Jim Miller19a52672012-10-23 19:52:04 -0700413 break;
414 case Gravity.BOTTOM:
415 bottom = fixedLayoutVertical
Adam Powell97997142012-11-06 21:32:42 -0800416 ? padding.top + height - (adjustedHeight - childHeight) / 2
417 : padding.top + height;
Jim Miller19a52672012-10-23 19:52:04 -0700418 top = bottom - childHeight;
Adam Powellc0657fb2012-10-24 14:00:04 -0700419 if (adjustPadding && isVertical) {
420 padding.bottom = height - top;
421 padding.top += childHeight / 2;
422 }
Jim Miller19a52672012-10-23 19:52:04 -0700423 break;
424 case Gravity.CENTER_VERTICAL:
Adam Powell9d34f9d2012-11-06 15:25:05 -0800425 top = padding.top + (height - childHeight) / 2;
Jim Miller19a52672012-10-23 19:52:04 -0700426 bottom = top + childHeight;
427 break;
428 }
429 switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
430 case Gravity.LEFT:
431 left = fixedLayoutHorizontal ?
432 padding.left + (adjustedWidth - childWidth) / 2 : padding.left;
433 right = left + childWidth;
Adam Powellc0657fb2012-10-24 14:00:04 -0700434 if (adjustPadding && isHorizontal && !isVertical) {
435 padding.left = right;
436 padding.right += childWidth / 2;
437 }
Jim Miller19a52672012-10-23 19:52:04 -0700438 break;
439 case Gravity.RIGHT:
440 right = fixedLayoutHorizontal
441 ? width - padding.right - (adjustedWidth - childWidth) / 2
442 : width - padding.right;
443 left = right - childWidth;
Adam Powellc0657fb2012-10-24 14:00:04 -0700444 if (adjustPadding && isHorizontal && !isVertical) {
445 padding.right = width - left;
446 padding.left += childWidth / 2;
447 }
Jim Miller19a52672012-10-23 19:52:04 -0700448 break;
449 case Gravity.CENTER_HORIZONTAL:
Adam Powellc0657fb2012-10-24 14:00:04 -0700450 final int paddedWidth = width - padding.left - padding.right;
451 left = (paddedWidth - childWidth) / 2;
Jim Miller19a52672012-10-23 19:52:04 -0700452 right = left + childWidth;
453 break;
454 }
John Spurlock256ae672013-09-26 12:14:33 -0400455 top += mInsets.top;
456 bottom += mInsets.top;
Jim Miller19a52672012-10-23 19:52:04 -0700457 child.layout(left, top, right, bottom);
458 }
459
460 @Override
461 public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
462 return new LayoutParams(getContext(), attrs, this);
463 }
464
465 @Override
466 protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
467 return p instanceof LayoutParams ? new LayoutParams((LayoutParams) p) :
468 p instanceof MarginLayoutParams ? new LayoutParams((MarginLayoutParams) p) :
469 new LayoutParams(p);
470 }
471
472 @Override
473 protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
474 return new LayoutParams();
475 }
476
477 @Override
478 protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
479 return p instanceof LayoutParams;
480 }
481
482 public static class LayoutParams extends MarginLayoutParams {
483
484 public float centerWithinArea = 0;
485
486 public int childType = 0;
487
488 public static final int CHILD_TYPE_NONE = 0;
489 public static final int CHILD_TYPE_WIDGET = 1;
490 public static final int CHILD_TYPE_CHALLENGE = 2;
491 public static final int CHILD_TYPE_USER_SWITCHER = 3;
Adam Powelleee20932012-10-24 16:26:56 -0700492 public static final int CHILD_TYPE_SCRIM = 4;
Winson Chungc065a5d2012-11-07 17:17:33 -0800493 public static final int CHILD_TYPE_PAGE_DELETE_DROP_TARGET = 7;
Jim Miller19a52672012-10-23 19:52:04 -0700494
495 public int gravity = Gravity.NO_GRAVITY;
496
497 public int maxWidth = -1;
498 public int maxHeight = -1;
499
500 public LayoutParams() {
501 this(WRAP_CONTENT, WRAP_CONTENT);
502 }
503
504 LayoutParams(Context c, AttributeSet attrs, MultiPaneChallengeLayout parent) {
505 super(c, attrs);
506
507 final TypedArray a = c.obtainStyledAttributes(attrs,
508 R.styleable.MultiPaneChallengeLayout_Layout);
509
510 centerWithinArea = a.getFloat(
511 R.styleable.MultiPaneChallengeLayout_Layout_layout_centerWithinArea, 0);
512 childType = a.getInt(R.styleable.MultiPaneChallengeLayout_Layout_layout_childType,
513 CHILD_TYPE_NONE);
514 gravity = a.getInt(R.styleable.MultiPaneChallengeLayout_Layout_layout_gravity,
515 Gravity.NO_GRAVITY);
516 maxWidth = a.getDimensionPixelSize(
517 R.styleable.MultiPaneChallengeLayout_Layout_layout_maxWidth, -1);
518 maxHeight = a.getDimensionPixelSize(
519 R.styleable.MultiPaneChallengeLayout_Layout_layout_maxHeight, -1);
520
521 // Default gravity settings based on type and parent orientation
522 if (gravity == Gravity.NO_GRAVITY) {
523 if (parent.mOrientation == HORIZONTAL) {
524 switch (childType) {
525 case CHILD_TYPE_WIDGET:
526 gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;
527 break;
528 case CHILD_TYPE_CHALLENGE:
529 gravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL;
530 break;
531 case CHILD_TYPE_USER_SWITCHER:
532 gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
533 break;
534 }
535 } else {
536 switch (childType) {
537 case CHILD_TYPE_WIDGET:
538 gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
539 break;
540 case CHILD_TYPE_CHALLENGE:
541 gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
542 break;
543 case CHILD_TYPE_USER_SWITCHER:
544 gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
545 break;
546 }
547 }
548 }
549
550 a.recycle();
551 }
552
553 public LayoutParams(int width, int height) {
554 super(width, height);
555 }
556
557 public LayoutParams(ViewGroup.LayoutParams source) {
558 super(source);
559 }
560
561 public LayoutParams(MarginLayoutParams source) {
562 super(source);
563 }
564
565 public LayoutParams(LayoutParams source) {
566 this((MarginLayoutParams) source);
567
568 centerWithinArea = source.centerWithinArea;
569 childType = source.childType;
570 gravity = source.gravity;
571 maxWidth = source.maxWidth;
572 maxHeight = source.maxHeight;
573 }
574 }
575}