blob: 8fd39c00a7feedae34a3835f73e4ab61a974812f [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();
Adam Powell9d34f9d2012-11-06 15:25:05 -080050
51 private final DisplayMetrics mDisplayMetrics;
Jim Miller19a52672012-10-23 19:52:04 -070052
Adam Powelleee20932012-10-24 16:26:56 -070053 private final OnClickListener mScrimClickListener = new OnClickListener() {
54 @Override
55 public void onClick(View v) {
56 hideBouncer();
57 }
58 };
59
Jim Miller19a52672012-10-23 19:52:04 -070060 public MultiPaneChallengeLayout(Context context) {
61 this(context, null);
62 }
63
64 public MultiPaneChallengeLayout(Context context, AttributeSet attrs) {
65 this(context, attrs, 0);
66 }
67
68 public MultiPaneChallengeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
69 super(context, attrs, defStyleAttr);
70
71 final TypedArray a = context.obtainStyledAttributes(attrs,
72 R.styleable.MultiPaneChallengeLayout, defStyleAttr, 0);
Jim Miller5ecd8112013-01-09 18:50:26 -080073 mOrientation = a.getInt(R.styleable.MultiPaneChallengeLayout_android_orientation,
Jim Miller19a52672012-10-23 19:52:04 -070074 HORIZONTAL);
75 a.recycle();
Adam Powell9d34f9d2012-11-06 15:25:05 -080076
77 final Resources res = getResources();
78 mDisplayMetrics = res.getDisplayMetrics();
Adam Powelleec4fe22012-11-07 18:07:15 -080079
80 setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_STABLE);
Jim Miller19a52672012-10-23 19:52:04 -070081 }
82
83 @Override
84 public boolean isChallengeShowing() {
85 return true;
86 }
87
88 @Override
89 public boolean isChallengeOverlapping() {
90 return false;
91 }
92
93 @Override
94 public void showChallenge(boolean b) {
95 }
96
97 @Override
Winson Chung70c2f872012-11-07 21:47:12 -080098 public int getBouncerAnimationDuration() {
99 return ANIMATE_BOUNCE_DURATION;
100 }
101
102 @Override
Jim Miller19a52672012-10-23 19:52:04 -0700103 public void showBouncer() {
Adam Powelleee20932012-10-24 16:26:56 -0700104 if (mIsBouncing) return;
105 mIsBouncing = true;
106 if (mScrimView != null) {
Chris Wrenc3451462012-10-30 11:22:58 -0400107 if (mChallengeView != null) {
108 mChallengeView.showBouncer(ANIMATE_BOUNCE_DURATION);
109 }
110
111 Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 1f);
112 anim.setDuration(ANIMATE_BOUNCE_DURATION);
113 anim.addListener(new AnimatorListenerAdapter() {
114 @Override
115 public void onAnimationStart(Animator animation) {
116 mScrimView.setVisibility(VISIBLE);
117 }
118 });
119 anim.start();
Adam Powelleee20932012-10-24 16:26:56 -0700120 }
Adam Powell0b1b5522012-10-25 13:39:30 -0700121 if (mBouncerListener != null) {
122 mBouncerListener.onBouncerStateChanged(true);
123 }
Adam Powelleee20932012-10-24 16:26:56 -0700124 }
125
126 @Override
127 public void hideBouncer() {
128 if (!mIsBouncing) return;
129 mIsBouncing = false;
130 if (mScrimView != null) {
Chris Wrenc3451462012-10-30 11:22:58 -0400131 if (mChallengeView != null) {
132 mChallengeView.hideBouncer(ANIMATE_BOUNCE_DURATION);
133 }
134
135 Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 0f);
136 anim.setDuration(ANIMATE_BOUNCE_DURATION);
137 anim.addListener(new AnimatorListenerAdapter() {
138 @Override
139 public void onAnimationEnd(Animator animation) {
140 mScrimView.setVisibility(INVISIBLE);
141 }
142 });
143 anim.start();
Adam Powelleee20932012-10-24 16:26:56 -0700144 }
Adam Powell0b1b5522012-10-25 13:39:30 -0700145 if (mBouncerListener != null) {
146 mBouncerListener.onBouncerStateChanged(false);
147 }
Adam Powelleee20932012-10-24 16:26:56 -0700148 }
149
150 @Override
151 public boolean isBouncing() {
152 return mIsBouncing;
153 }
154
Adam Powell0b1b5522012-10-25 13:39:30 -0700155 @Override
156 public void setOnBouncerStateChangedListener(OnBouncerStateChangedListener listener) {
157 mBouncerListener = listener;
158 }
159
160 @Override
161 public void requestChildFocus(View child, View focused) {
162 if (mIsBouncing && child != mChallengeView) {
163 // Clear out of the bouncer if the user tries to move focus outside of
164 // the security challenge view.
165 hideBouncer();
166 }
167 super.requestChildFocus(child, focused);
168 }
169
Adam Powelleee20932012-10-24 16:26:56 -0700170 void setScrimView(View scrim) {
171 if (mScrimView != null) {
172 mScrimView.setOnClickListener(null);
173 }
174 mScrimView = scrim;
Chris Wrenc3451462012-10-30 11:22:58 -0400175 mScrimView.setAlpha(mIsBouncing ? 1.0f : 0.0f);
176 mScrimView.setVisibility(mIsBouncing ? VISIBLE : INVISIBLE);
Adam Powelleee20932012-10-24 16:26:56 -0700177 mScrimView.setFocusable(true);
178 mScrimView.setOnClickListener(mScrimClickListener);
Jim Miller19a52672012-10-23 19:52:04 -0700179 }
180
Adam Powell9d34f9d2012-11-06 15:25:05 -0800181 private int getVirtualHeight(LayoutParams lp, int height, int heightUsed) {
182 int virtualHeight = height;
183 final View root = getRootView();
184 if (root != null) {
185 // This calculation is super dodgy and relies on several assumptions.
186 // Specifically that the root of the window will be padded in for insets
187 // and that the window is LAYOUT_IN_SCREEN.
188 virtualHeight = mDisplayMetrics.heightPixels - root.getPaddingTop();
189 }
190 if (lp.childType == LayoutParams.CHILD_TYPE_WIDGET ||
191 lp.childType == LayoutParams.CHILD_TYPE_USER_SWITCHER) {
192 // Always measure the widget pager/user switcher as if there were no IME insets
193 // on the window. We want to avoid resizing widgets when possible as it can
194 // be ugly/expensive. This lets us simply clip them instead.
195 return virtualHeight - heightUsed;
Winson Chungc065a5d2012-11-07 17:17:33 -0800196 } else if (lp.childType == LayoutParams.CHILD_TYPE_PAGE_DELETE_DROP_TARGET) {
197 return height;
Adam Powell9d34f9d2012-11-06 15:25:05 -0800198 }
199 return Math.min(virtualHeight - heightUsed, height);
200 }
201
Jim Miller19a52672012-10-23 19:52:04 -0700202 @Override
Adam Powell9d34f9d2012-11-06 15:25:05 -0800203 protected void onMeasure(final int widthSpec, final int heightSpec) {
Jim Miller19a52672012-10-23 19:52:04 -0700204 if (MeasureSpec.getMode(widthSpec) != MeasureSpec.EXACTLY ||
205 MeasureSpec.getMode(heightSpec) != MeasureSpec.EXACTLY) {
206 throw new IllegalArgumentException(
207 "MultiPaneChallengeLayout must be measured with an exact size");
208 }
209
210 final int width = MeasureSpec.getSize(widthSpec);
211 final int height = MeasureSpec.getSize(heightSpec);
212 setMeasuredDimension(width, height);
213
214 int widthUsed = 0;
215 int heightUsed = 0;
216
217 // First pass. Find the challenge view and measure the user switcher,
218 // which consumes space in the layout.
219 mChallengeView = null;
220 mUserSwitcherView = null;
221 final int count = getChildCount();
222 for (int i = 0; i < count; i++) {
223 final View child = getChildAt(i);
224 final LayoutParams lp = (LayoutParams) child.getLayoutParams();
225
226 if (lp.childType == LayoutParams.CHILD_TYPE_CHALLENGE) {
227 if (mChallengeView != null) {
228 throw new IllegalStateException(
229 "There may only be one child of type challenge");
230 }
Chris Wrenc3451462012-10-30 11:22:58 -0400231 if (!(child instanceof KeyguardSecurityContainer)) {
232 throw new IllegalArgumentException(
233 "Challenge must be a KeyguardSecurityContainer");
234 }
235 mChallengeView = (KeyguardSecurityContainer) child;
Jim Miller19a52672012-10-23 19:52:04 -0700236 } else if (lp.childType == LayoutParams.CHILD_TYPE_USER_SWITCHER) {
237 if (mUserSwitcherView != null) {
238 throw new IllegalStateException(
239 "There may only be one child of type userSwitcher");
240 }
241 mUserSwitcherView = child;
242
243 if (child.getVisibility() == GONE) continue;
244
Adam Powell9d34f9d2012-11-06 15:25:05 -0800245 int adjustedWidthSpec = widthSpec;
246 int adjustedHeightSpec = heightSpec;
247 if (lp.maxWidth >= 0) {
248 adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
249 Math.min(lp.maxWidth, width), MeasureSpec.EXACTLY);
250 }
251 if (lp.maxHeight >= 0) {
252 adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
253 Math.min(lp.maxHeight, height), MeasureSpec.EXACTLY);
254 }
255 // measureChildWithMargins will resolve layout direction for the LayoutParams
256 measureChildWithMargins(child, adjustedWidthSpec, 0, adjustedHeightSpec, 0);
257
258 // Only subtract out space from one dimension. Favor vertical.
259 // Offset by 1.5x to add some balance along the other edge.
260 if (Gravity.isVertical(lp.gravity)) {
261 heightUsed += child.getMeasuredHeight() * 1.5f;
262 } else if (Gravity.isHorizontal(lp.gravity)) {
263 widthUsed += child.getMeasuredWidth() * 1.5f;
Jim Miller19a52672012-10-23 19:52:04 -0700264 }
Adam Powelleee20932012-10-24 16:26:56 -0700265 } else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) {
266 setScrimView(child);
267 child.measure(widthSpec, heightSpec);
Jim Miller19a52672012-10-23 19:52:04 -0700268 }
269 }
270
271 // Second pass. Measure everything that's left.
272 for (int i = 0; i < count; i++) {
273 final View child = getChildAt(i);
274 final LayoutParams lp = (LayoutParams) child.getLayoutParams();
275
276 if (lp.childType == LayoutParams.CHILD_TYPE_USER_SWITCHER ||
Adam Powelleee20932012-10-24 16:26:56 -0700277 lp.childType == LayoutParams.CHILD_TYPE_SCRIM ||
Jim Miller19a52672012-10-23 19:52:04 -0700278 child.getVisibility() == GONE) {
279 // Don't need to measure GONE children, and the user switcher was already measured.
280 continue;
281 }
282
Adam Powell9d34f9d2012-11-06 15:25:05 -0800283 final int virtualHeight = getVirtualHeight(lp, height, heightUsed);
284
Jim Miller19a52672012-10-23 19:52:04 -0700285 int adjustedWidthSpec;
286 int adjustedHeightSpec;
287 if (lp.centerWithinArea > 0) {
288 if (mOrientation == HORIZONTAL) {
289 adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
Adam Powell0a27c482012-10-26 17:00:52 -0700290 (int) ((width - widthUsed) * lp.centerWithinArea + 0.5f),
291 MeasureSpec.EXACTLY);
Jim Miller19a52672012-10-23 19:52:04 -0700292 adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
Adam Powell9d34f9d2012-11-06 15:25:05 -0800293 virtualHeight, MeasureSpec.EXACTLY);
Adam Powell0a27c482012-10-26 17:00:52 -0700294 } else {
295 adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
Adam Powell9d34f9d2012-11-06 15:25:05 -0800296 width - widthUsed, MeasureSpec.EXACTLY);
Adam Powell0a27c482012-10-26 17:00:52 -0700297 adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
Adam Powell9d34f9d2012-11-06 15:25:05 -0800298 (int) (virtualHeight * lp.centerWithinArea + 0.5f),
Adam Powell0a27c482012-10-26 17:00:52 -0700299 MeasureSpec.EXACTLY);
Jim Miller19a52672012-10-23 19:52:04 -0700300 }
301 } else {
Adam Powell0a27c482012-10-26 17:00:52 -0700302 adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
Adam Powell9d34f9d2012-11-06 15:25:05 -0800303 width - widthUsed, MeasureSpec.EXACTLY);
Adam Powell0a27c482012-10-26 17:00:52 -0700304 adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
Adam Powell9d34f9d2012-11-06 15:25:05 -0800305 virtualHeight, MeasureSpec.EXACTLY);
Jim Miller19a52672012-10-23 19:52:04 -0700306 }
307 if (lp.maxWidth >= 0) {
308 adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
Adam Powell0a27c482012-10-26 17:00:52 -0700309 Math.min(lp.maxWidth, MeasureSpec.getSize(adjustedWidthSpec)),
Jim Miller19a52672012-10-23 19:52:04 -0700310 MeasureSpec.EXACTLY);
311 }
312 if (lp.maxHeight >= 0) {
313 adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
Adam Powell0a27c482012-10-26 17:00:52 -0700314 Math.min(lp.maxHeight, MeasureSpec.getSize(adjustedHeightSpec)),
Jim Miller19a52672012-10-23 19:52:04 -0700315 MeasureSpec.EXACTLY);
316 }
317
Adam Powell0a27c482012-10-26 17:00:52 -0700318 measureChildWithMargins(child, adjustedWidthSpec, 0, adjustedHeightSpec, 0);
Jim Miller19a52672012-10-23 19:52:04 -0700319 }
320 }
321
322 @Override
323 protected void onLayout(boolean changed, int l, int t, int r, int b) {
324 final Rect padding = mTempRect;
325 padding.left = getPaddingLeft();
326 padding.top = getPaddingTop();
327 padding.right = getPaddingRight();
328 padding.bottom = getPaddingBottom();
329 final int width = r - l;
330 final int height = b - t;
331
332 // Reserve extra space in layout for the user switcher by modifying
333 // local padding during this layout pass
334 if (mUserSwitcherView != null && mUserSwitcherView.getVisibility() != GONE) {
335 layoutWithGravity(width, height, mUserSwitcherView, padding, true);
336 }
337
338 final int count = getChildCount();
339 for (int i = 0; i < count; i++) {
340 final View child = getChildAt(i);
Winson Chungc065a5d2012-11-07 17:17:33 -0800341 LayoutParams lp = (LayoutParams) child.getLayoutParams();
Jim Miller19a52672012-10-23 19:52:04 -0700342
343 // We did the user switcher above if we have one.
344 if (child == mUserSwitcherView || child.getVisibility() == GONE) continue;
345
Adam Powelleee20932012-10-24 16:26:56 -0700346 if (child == mScrimView) {
347 child.layout(0, 0, width, height);
348 continue;
Winson Chungc065a5d2012-11-07 17:17:33 -0800349 } else if (lp.childType == LayoutParams.CHILD_TYPE_PAGE_DELETE_DROP_TARGET) {
350 layoutWithGravity(width, height, child, mZeroPadding, false);
351 continue;
Adam Powelleee20932012-10-24 16:26:56 -0700352 }
353
Jim Miller19a52672012-10-23 19:52:04 -0700354 layoutWithGravity(width, height, child, padding, false);
355 }
356 }
357
358 private void layoutWithGravity(int width, int height, View child, Rect padding,
359 boolean adjustPadding) {
360 final LayoutParams lp = (LayoutParams) child.getLayoutParams();
361
Adam Powell9d34f9d2012-11-06 15:25:05 -0800362 final int heightUsed = padding.top + padding.bottom - getPaddingTop() - getPaddingBottom();
363 height = getVirtualHeight(lp, height, heightUsed);
364
Jim Miller19a52672012-10-23 19:52:04 -0700365 final int gravity = Gravity.getAbsoluteGravity(lp.gravity, getLayoutDirection());
366
367 final boolean fixedLayoutSize = lp.centerWithinArea > 0;
368 final boolean fixedLayoutHorizontal = fixedLayoutSize && mOrientation == HORIZONTAL;
369 final boolean fixedLayoutVertical = fixedLayoutSize && mOrientation == VERTICAL;
370
371 final int adjustedWidth;
372 final int adjustedHeight;
373 if (fixedLayoutHorizontal) {
Adam Powellc0657fb2012-10-24 14:00:04 -0700374 final int paddedWidth = width - padding.left - padding.right;
375 adjustedWidth = (int) (paddedWidth * lp.centerWithinArea + 0.5f);
Jim Miller19a52672012-10-23 19:52:04 -0700376 adjustedHeight = height;
377 } else if (fixedLayoutVertical) {
Adam Powelleeb62552012-11-07 14:07:23 -0800378 final int paddedHeight = height - getPaddingTop() - getPaddingBottom();
Jim Miller19a52672012-10-23 19:52:04 -0700379 adjustedWidth = width;
Adam Powellc0657fb2012-10-24 14:00:04 -0700380 adjustedHeight = (int) (paddedHeight * lp.centerWithinArea + 0.5f);
Jim Miller19a52672012-10-23 19:52:04 -0700381 } else {
382 adjustedWidth = width;
383 adjustedHeight = height;
384 }
385
386 final boolean isVertical = Gravity.isVertical(gravity);
387 final boolean isHorizontal = Gravity.isHorizontal(gravity);
388 final int childWidth = child.getMeasuredWidth();
389 final int childHeight = child.getMeasuredHeight();
390
391 int left = padding.left;
392 int top = padding.top;
393 int right = left + childWidth;
394 int bottom = top + childHeight;
395 switch (gravity & Gravity.VERTICAL_GRAVITY_MASK) {
396 case Gravity.TOP:
397 top = fixedLayoutVertical ?
398 padding.top + (adjustedHeight - childHeight) / 2 : padding.top;
399 bottom = top + childHeight;
Adam Powellc0657fb2012-10-24 14:00:04 -0700400 if (adjustPadding && isVertical) {
401 padding.top = bottom;
402 padding.bottom += childHeight / 2;
403 }
Jim Miller19a52672012-10-23 19:52:04 -0700404 break;
405 case Gravity.BOTTOM:
406 bottom = fixedLayoutVertical
Adam Powell97997142012-11-06 21:32:42 -0800407 ? padding.top + height - (adjustedHeight - childHeight) / 2
408 : padding.top + height;
Jim Miller19a52672012-10-23 19:52:04 -0700409 top = bottom - childHeight;
Adam Powellc0657fb2012-10-24 14:00:04 -0700410 if (adjustPadding && isVertical) {
411 padding.bottom = height - top;
412 padding.top += childHeight / 2;
413 }
Jim Miller19a52672012-10-23 19:52:04 -0700414 break;
415 case Gravity.CENTER_VERTICAL:
Adam Powell9d34f9d2012-11-06 15:25:05 -0800416 top = padding.top + (height - childHeight) / 2;
Jim Miller19a52672012-10-23 19:52:04 -0700417 bottom = top + childHeight;
418 break;
419 }
420 switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
421 case Gravity.LEFT:
422 left = fixedLayoutHorizontal ?
423 padding.left + (adjustedWidth - childWidth) / 2 : padding.left;
424 right = left + childWidth;
Adam Powellc0657fb2012-10-24 14:00:04 -0700425 if (adjustPadding && isHorizontal && !isVertical) {
426 padding.left = right;
427 padding.right += childWidth / 2;
428 }
Jim Miller19a52672012-10-23 19:52:04 -0700429 break;
430 case Gravity.RIGHT:
431 right = fixedLayoutHorizontal
432 ? width - padding.right - (adjustedWidth - childWidth) / 2
433 : width - padding.right;
434 left = right - childWidth;
Adam Powellc0657fb2012-10-24 14:00:04 -0700435 if (adjustPadding && isHorizontal && !isVertical) {
436 padding.right = width - left;
437 padding.left += childWidth / 2;
438 }
Jim Miller19a52672012-10-23 19:52:04 -0700439 break;
440 case Gravity.CENTER_HORIZONTAL:
Adam Powellc0657fb2012-10-24 14:00:04 -0700441 final int paddedWidth = width - padding.left - padding.right;
442 left = (paddedWidth - childWidth) / 2;
Jim Miller19a52672012-10-23 19:52:04 -0700443 right = left + childWidth;
444 break;
445 }
446 child.layout(left, top, right, bottom);
447 }
448
449 @Override
450 public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
451 return new LayoutParams(getContext(), attrs, this);
452 }
453
454 @Override
455 protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
456 return p instanceof LayoutParams ? new LayoutParams((LayoutParams) p) :
457 p instanceof MarginLayoutParams ? new LayoutParams((MarginLayoutParams) p) :
458 new LayoutParams(p);
459 }
460
461 @Override
462 protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
463 return new LayoutParams();
464 }
465
466 @Override
467 protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
468 return p instanceof LayoutParams;
469 }
470
471 public static class LayoutParams extends MarginLayoutParams {
472
473 public float centerWithinArea = 0;
474
475 public int childType = 0;
476
477 public static final int CHILD_TYPE_NONE = 0;
478 public static final int CHILD_TYPE_WIDGET = 1;
479 public static final int CHILD_TYPE_CHALLENGE = 2;
480 public static final int CHILD_TYPE_USER_SWITCHER = 3;
Adam Powelleee20932012-10-24 16:26:56 -0700481 public static final int CHILD_TYPE_SCRIM = 4;
Winson Chungc065a5d2012-11-07 17:17:33 -0800482 public static final int CHILD_TYPE_PAGE_DELETE_DROP_TARGET = 7;
Jim Miller19a52672012-10-23 19:52:04 -0700483
484 public int gravity = Gravity.NO_GRAVITY;
485
486 public int maxWidth = -1;
487 public int maxHeight = -1;
488
489 public LayoutParams() {
490 this(WRAP_CONTENT, WRAP_CONTENT);
491 }
492
493 LayoutParams(Context c, AttributeSet attrs, MultiPaneChallengeLayout parent) {
494 super(c, attrs);
495
496 final TypedArray a = c.obtainStyledAttributes(attrs,
497 R.styleable.MultiPaneChallengeLayout_Layout);
498
499 centerWithinArea = a.getFloat(
500 R.styleable.MultiPaneChallengeLayout_Layout_layout_centerWithinArea, 0);
501 childType = a.getInt(R.styleable.MultiPaneChallengeLayout_Layout_layout_childType,
502 CHILD_TYPE_NONE);
503 gravity = a.getInt(R.styleable.MultiPaneChallengeLayout_Layout_layout_gravity,
504 Gravity.NO_GRAVITY);
505 maxWidth = a.getDimensionPixelSize(
506 R.styleable.MultiPaneChallengeLayout_Layout_layout_maxWidth, -1);
507 maxHeight = a.getDimensionPixelSize(
508 R.styleable.MultiPaneChallengeLayout_Layout_layout_maxHeight, -1);
509
510 // Default gravity settings based on type and parent orientation
511 if (gravity == Gravity.NO_GRAVITY) {
512 if (parent.mOrientation == HORIZONTAL) {
513 switch (childType) {
514 case CHILD_TYPE_WIDGET:
515 gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;
516 break;
517 case CHILD_TYPE_CHALLENGE:
518 gravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL;
519 break;
520 case CHILD_TYPE_USER_SWITCHER:
521 gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
522 break;
523 }
524 } else {
525 switch (childType) {
526 case CHILD_TYPE_WIDGET:
527 gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
528 break;
529 case CHILD_TYPE_CHALLENGE:
530 gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
531 break;
532 case CHILD_TYPE_USER_SWITCHER:
533 gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
534 break;
535 }
536 }
537 }
538
539 a.recycle();
540 }
541
542 public LayoutParams(int width, int height) {
543 super(width, height);
544 }
545
546 public LayoutParams(ViewGroup.LayoutParams source) {
547 super(source);
548 }
549
550 public LayoutParams(MarginLayoutParams source) {
551 super(source);
552 }
553
554 public LayoutParams(LayoutParams source) {
555 this((MarginLayoutParams) source);
556
557 centerWithinArea = source.centerWithinArea;
558 childType = source.childType;
559 gravity = source.gravity;
560 maxWidth = source.maxWidth;
561 maxHeight = source.maxHeight;
562 }
563 }
564}