* commit '732916aafe681d1bafbd22bc2a7884b689a57fd3': Refactoring CellLayout into three classes
This commit is contained in:
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.launcher2;
|
||||
|
||||
import com.android.launcher.R;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Bitmap.Config;
|
||||
import android.graphics.PorterDuff.Mode;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
// This class caches the drawing of this View's children in a bitmap when the scale factor
|
||||
// falls below a certain size. Only used by CellLayout, but in a separate class to keep cache
|
||||
// logic separate from the other logic in CellLayout
|
||||
public class CachedViewGroup extends ViewGroup implements VisibilityChangedListener {
|
||||
static final String TAG = "CachedViewGroup";
|
||||
|
||||
private Bitmap mCache;
|
||||
private Canvas mCacheCanvas;
|
||||
private Rect mCacheRect;
|
||||
private Paint mCachePaint;
|
||||
|
||||
private boolean mIsCacheEnabled = true;
|
||||
private boolean mDisableCacheUpdates = false;
|
||||
private boolean mForceCacheUpdate = false;
|
||||
private boolean isUpdatingCache = false;
|
||||
private boolean mIsCacheDirty = true;
|
||||
private float mBitmapCacheScale;
|
||||
private float mMaxScaleForUsingBitmapCache;
|
||||
|
||||
private Rect mBackgroundRect;
|
||||
|
||||
public CachedViewGroup(Context context) {
|
||||
super(context);
|
||||
mBackgroundRect = new Rect();
|
||||
mCacheRect = new Rect();
|
||||
final Resources res = getResources();
|
||||
mBitmapCacheScale =
|
||||
res.getInteger(R.integer.config_workspaceScreenBitmapCacheScale) / 100.0f;
|
||||
mMaxScaleForUsingBitmapCache =
|
||||
res.getInteger(R.integer.config_maxScaleForUsingWorkspaceScreenBitmapCache) / 100.0f;
|
||||
mCacheCanvas = new Canvas();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
// sub-classes (namely CellLayout) will need to implement this
|
||||
prepareCacheBitmap();
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
private void invalidateIfNeeded() {
|
||||
if (mIsCacheDirty) {
|
||||
// Force a redraw to update the cache if it's dirty
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public void enableCache() {
|
||||
mIsCacheEnabled = true;
|
||||
invalidateIfNeeded();
|
||||
}
|
||||
|
||||
public void disableCache() {
|
||||
mIsCacheEnabled = false;
|
||||
}
|
||||
|
||||
public void disableCacheUpdates() {
|
||||
mDisableCacheUpdates = true;
|
||||
// Force just one update before we enter a period of no cache updates
|
||||
mForceCacheUpdate = true;
|
||||
}
|
||||
|
||||
public void enableCacheUpdates() {
|
||||
mDisableCacheUpdates = false;
|
||||
invalidateIfNeeded();
|
||||
}
|
||||
|
||||
private void invalidateCache() {
|
||||
mIsCacheDirty = true;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void receiveVisibilityChangedMessage(View v) {
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
private void prepareCacheBitmap() {
|
||||
if (mCache == null) {
|
||||
mCache = Bitmap.createBitmap((int) (getWidth() * mBitmapCacheScale),
|
||||
(int) (getHeight() * mBitmapCacheScale), Config.ARGB_8888);
|
||||
|
||||
mCachePaint = new Paint();
|
||||
mCachePaint.setFilterBitmap(true);
|
||||
mCacheCanvas.setBitmap(mCache);
|
||||
mCacheCanvas.scale(mBitmapCacheScale, mBitmapCacheScale);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void updateCache() {
|
||||
mCacheCanvas.drawColor(0, Mode.CLEAR);
|
||||
|
||||
float alpha = getAlpha();
|
||||
setAlpha(1.0f);
|
||||
isUpdatingCache = true;
|
||||
draw(mCacheCanvas);
|
||||
isUpdatingCache = false;
|
||||
setAlpha(alpha);
|
||||
|
||||
mIsCacheDirty = false;
|
||||
}
|
||||
|
||||
|
||||
public void drawChildren(Canvas canvas) {
|
||||
super.dispatchDraw(canvas);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllViews() {
|
||||
super.removeAllViews();
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllViewsInLayout() {
|
||||
super.removeAllViewsInLayout();
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
public void removeViewWithoutMarkingCells(View view) {
|
||||
super.removeView(view);
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeView(View view) {
|
||||
super.removeView(view);
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeViewAt(int index) {
|
||||
super.removeViewAt(index);
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeViewInLayout(View view) {
|
||||
super.removeViewInLayout(view);
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeViews(int start, int count) {
|
||||
super.removeViews(start, count);
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeViewsInLayout(int start, int count) {
|
||||
super.removeViewsInLayout(start, count);
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchDraw(Canvas canvas) {
|
||||
final int count = getChildCount();
|
||||
|
||||
boolean useBitmapCache = false;
|
||||
if (!isUpdatingCache) {
|
||||
if (!mIsCacheDirty) {
|
||||
// Check if one of the children (an icon or widget) is dirty
|
||||
for (int i = 0; i < count; i++) {
|
||||
final View child = getChildAt(i);
|
||||
if (child.isDirty()) {
|
||||
mIsCacheDirty = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useBitmapCache = mIsCacheEnabled && getScaleX() < mMaxScaleForUsingBitmapCache;
|
||||
if (mForceCacheUpdate ||
|
||||
(useBitmapCache && !mDisableCacheUpdates)) {
|
||||
// Sometimes we force a cache update-- this is used to make sure the cache will look as
|
||||
// up-to-date as possible right when we disable cache updates
|
||||
if (mIsCacheDirty) {
|
||||
updateCache();
|
||||
}
|
||||
mForceCacheUpdate = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (useBitmapCache) {
|
||||
mCachePaint.setAlpha((int)(255*getAlpha()));
|
||||
canvas.drawBitmap(mCache, mCacheRect, mBackgroundRect, mCachePaint);
|
||||
} else {
|
||||
super.dispatchDraw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addView(View child, int index, ViewGroup.LayoutParams params) {
|
||||
super.addView(child, index, params);
|
||||
|
||||
// invalidate the cache to have it reflect the new item
|
||||
invalidateCache();
|
||||
|
||||
if (child instanceof VisibilityChangedBroadcaster) {
|
||||
VisibilityChangedBroadcaster v = (VisibilityChangedBroadcaster) child;
|
||||
v.setVisibilityChangedListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
mBackgroundRect.set(0, 0, w, h);
|
||||
mCacheRect.set(0, 0, (int) (mBitmapCacheScale * w), (int) (mBitmapCacheScale * h));
|
||||
mCache = null;
|
||||
prepareCacheBitmap();
|
||||
invalidateCache();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Custom interfaces used to listen to "visibility changed" events of *children* of Views. Avoided
|
||||
//using "onVisibilityChanged" in the names because there's a method of that name in framework
|
||||
//(which can only can be used to listen to ancestors' "visibility changed" events)
|
||||
interface VisibilityChangedBroadcaster {
|
||||
public void setVisibilityChangedListener(VisibilityChangedListener listener);
|
||||
}
|
||||
|
||||
interface VisibilityChangedListener {
|
||||
public void receiveVisibilityChangedMessage(View v);
|
||||
}
|
||||
@@ -25,7 +25,6 @@ import android.animation.ObjectAnimator;
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.animation.ValueAnimator.AnimatorUpdateListener;
|
||||
import android.app.WallpaperManager;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
@@ -37,8 +36,6 @@ import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Region;
|
||||
import android.graphics.Bitmap.Config;
|
||||
import android.graphics.PorterDuff.Mode;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
@@ -53,7 +50,7 @@ import android.view.animation.LayoutAnimationController;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class CellLayout extends ViewGroup implements VisibilityChangedListener {
|
||||
public class CellLayout extends ViewGroup {
|
||||
static final String TAG = "CellLayout";
|
||||
|
||||
private int mCellWidth;
|
||||
@@ -99,18 +96,6 @@ public class CellLayout extends ViewGroup implements VisibilityChangedListener {
|
||||
private float mGlowBackgroundScale;
|
||||
private float mGlowBackgroundAlpha;
|
||||
|
||||
private Bitmap mCache;
|
||||
private Canvas mCacheCanvas;
|
||||
private Rect mCacheRect;
|
||||
private Paint mCachePaint;
|
||||
|
||||
private boolean mIsCacheEnabled = true;
|
||||
private boolean mDisableCacheUpdates = false;
|
||||
private boolean mForceCacheUpdate = false;
|
||||
private boolean mIsCacheDirty = true;
|
||||
private float mBitmapCacheScale;
|
||||
private float mMaxScaleForUsingBitmapCache;
|
||||
|
||||
private boolean mAcceptsDrops = false;
|
||||
// If we're actively dragging something over this screen, mIsDragOverlapping is true
|
||||
private boolean mIsDragOverlapping = false;
|
||||
@@ -136,11 +121,10 @@ public class CellLayout extends ViewGroup implements VisibilityChangedListener {
|
||||
// When a drag operation is in progress, holds the nearest cell to the touch point
|
||||
private final int[] mDragCell = new int[2];
|
||||
|
||||
private final WallpaperManager mWallpaperManager;
|
||||
|
||||
private boolean mDragging = false;
|
||||
|
||||
private TimeInterpolator mEaseOutInterpolator;
|
||||
private CellLayoutChildren mChildren;
|
||||
|
||||
public CellLayout(Context context) {
|
||||
this(context, null);
|
||||
@@ -181,8 +165,6 @@ public class CellLayout extends ViewGroup implements VisibilityChangedListener {
|
||||
|
||||
setAlwaysDrawnWithCacheEnabled(false);
|
||||
|
||||
mWallpaperManager = WallpaperManager.getInstance(context);
|
||||
|
||||
final Resources res = getResources();
|
||||
|
||||
if (LauncherApplication.isScreenXLarge()) {
|
||||
@@ -279,15 +261,13 @@ public class CellLayout extends ViewGroup implements VisibilityChangedListener {
|
||||
|
||||
mBackgroundRect = new Rect();
|
||||
mGlowBackgroundRect = new Rect();
|
||||
mCacheRect = new Rect();
|
||||
setHoverScale(1.0f);
|
||||
setHoverAlpha(1.0f);
|
||||
|
||||
mBitmapCacheScale =
|
||||
res.getInteger(R.integer.config_workspaceScreenBitmapCacheScale) / 100.0f;
|
||||
mMaxScaleForUsingBitmapCache =
|
||||
res.getInteger(R.integer.config_maxScaleForUsingWorkspaceScreenBitmapCache) / 100.0f;
|
||||
mCacheCanvas = new Canvas();
|
||||
mChildren = new CellLayoutChildren(context);
|
||||
mChildren.setCellDimensions(
|
||||
mCellWidth, mCellHeight, mLeftPadding, mTopPadding, mWidthGap, mHeightGap);
|
||||
addView(mChildren);
|
||||
}
|
||||
|
||||
public void setIsDefaultDropTarget(boolean isDefaultDropTarget) {
|
||||
@@ -376,100 +356,12 @@ public class CellLayout extends ViewGroup implements VisibilityChangedListener {
|
||||
}
|
||||
}
|
||||
|
||||
public void drawChildren(Canvas canvas) {
|
||||
super.dispatchDraw(canvas);
|
||||
}
|
||||
|
||||
private void invalidateIfNeeded() {
|
||||
if (mIsCacheDirty) {
|
||||
// Force a redraw to update the cache if it's dirty
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public void enableCache() {
|
||||
mIsCacheEnabled = true;
|
||||
invalidateIfNeeded();
|
||||
}
|
||||
|
||||
public void disableCache() {
|
||||
mIsCacheEnabled = false;
|
||||
}
|
||||
|
||||
public void disableCacheUpdates() {
|
||||
mDisableCacheUpdates = true;
|
||||
// Force just one update before we enter a period of no cache updates
|
||||
mForceCacheUpdate = true;
|
||||
mChildren.disableCacheUpdates();
|
||||
}
|
||||
|
||||
public void enableCacheUpdates() {
|
||||
mDisableCacheUpdates = false;
|
||||
invalidateIfNeeded();
|
||||
}
|
||||
|
||||
private void invalidateCache() {
|
||||
mIsCacheDirty = true;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void receiveVisibilityChangedMessage(View v) {
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
public void updateCache() {
|
||||
mCacheCanvas.drawColor(0, Mode.CLEAR);
|
||||
|
||||
float alpha = getAlpha();
|
||||
setAlpha(1.0f);
|
||||
drawChildren(mCacheCanvas);
|
||||
setAlpha(alpha);
|
||||
|
||||
mIsCacheDirty = false;
|
||||
}
|
||||
|
||||
public void dispatchDraw(Canvas canvas) {
|
||||
final int count = getChildCount();
|
||||
|
||||
if (!mIsCacheDirty) {
|
||||
// Check if one of the children (an icon or widget) is dirty
|
||||
for (int i = 0; i < count; i++) {
|
||||
final View child = getChildAt(i);
|
||||
if (child.isDirty()) {
|
||||
mIsCacheDirty = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean useBitmapCache = mIsCacheEnabled && getScaleX() < mMaxScaleForUsingBitmapCache;
|
||||
if (mForceCacheUpdate ||
|
||||
(useBitmapCache && !mDisableCacheUpdates)) {
|
||||
// Sometimes we force a cache update-- this is used to make sure the cache will look as
|
||||
// up-to-date as possible right when we disable cache updates
|
||||
if (mIsCacheDirty) {
|
||||
updateCache();
|
||||
}
|
||||
mForceCacheUpdate = false;
|
||||
}
|
||||
|
||||
if (useBitmapCache) {
|
||||
mCachePaint.setAlpha((int)(255*getAlpha()));
|
||||
canvas.drawBitmap(mCache, mCacheRect, mBackgroundRect, mCachePaint);
|
||||
} else {
|
||||
super.dispatchDraw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
private void prepareCacheBitmap() {
|
||||
if (mCache == null) {
|
||||
mCache = Bitmap.createBitmap((int) (getWidth() * mBitmapCacheScale),
|
||||
(int) (getHeight() * mBitmapCacheScale), Config.ARGB_8888);
|
||||
|
||||
mCachePaint = new Paint();
|
||||
mCachePaint.setFilterBitmap(true);
|
||||
mCacheCanvas.setBitmap(mCache);
|
||||
mCacheCanvas.scale(mBitmapCacheScale, mBitmapCacheScale);
|
||||
}
|
||||
mChildren.enableCacheUpdates();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -610,15 +502,8 @@ public class CellLayout extends ViewGroup implements VisibilityChangedListener {
|
||||
|
||||
child.setId(childId);
|
||||
|
||||
addView(child, index, lp);
|
||||
child.setAlpha(getAlpha());
|
||||
if (child instanceof VisibilityChangedBroadcaster) {
|
||||
VisibilityChangedBroadcaster v = (VisibilityChangedBroadcaster) child;
|
||||
v.setVisibilityChangedListener(this);
|
||||
}
|
||||
mChildren.addView(child, index, lp);
|
||||
|
||||
// invalidate the cache to have it reflect the new item
|
||||
invalidateCache();
|
||||
if (markCells) markCellsAsOccupiedForView(child);
|
||||
|
||||
return true;
|
||||
@@ -639,70 +524,56 @@ public class CellLayout extends ViewGroup implements VisibilityChangedListener {
|
||||
|
||||
@Override
|
||||
public void removeAllViews() {
|
||||
super.removeAllViews();
|
||||
clearOccupiedCells();
|
||||
invalidateCache();
|
||||
mChildren.removeAllViews();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllViewsInLayout() {
|
||||
super.removeAllViewsInLayout();
|
||||
clearOccupiedCells();
|
||||
invalidateCache();
|
||||
mChildren.removeAllViewsInLayout();
|
||||
}
|
||||
|
||||
public void removeViewWithoutMarkingCells(View view) {
|
||||
super.removeView(view);
|
||||
invalidateCache();
|
||||
mChildren.removeViewWithoutMarkingCells(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeView(View view) {
|
||||
markCellsAsUnoccupiedForView(view);
|
||||
super.removeView(view);
|
||||
invalidateCache();
|
||||
mChildren.removeView(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeViewAt(int index) {
|
||||
markCellsAsUnoccupiedForView(getChildAt(index));
|
||||
super.removeViewAt(index);
|
||||
invalidateCache();
|
||||
markCellsAsUnoccupiedForView(mChildren.getChildAt(index));
|
||||
mChildren.removeViewAt(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeViewInLayout(View view) {
|
||||
markCellsAsUnoccupiedForView(view);
|
||||
super.removeViewInLayout(view);
|
||||
invalidateCache();
|
||||
mChildren.removeViewInLayout(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeViews(int start, int count) {
|
||||
for (int i = start; i < start + count; i++) {
|
||||
markCellsAsUnoccupiedForView(getChildAt(i));
|
||||
markCellsAsUnoccupiedForView(mChildren.getChildAt(i));
|
||||
}
|
||||
super.removeViews(start, count);
|
||||
invalidateCache();
|
||||
mChildren.removeViews(start, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeViewsInLayout(int start, int count) {
|
||||
for (int i = start; i < start + count; i++) {
|
||||
markCellsAsUnoccupiedForView(getChildAt(i));
|
||||
markCellsAsUnoccupiedForView(mChildren.getChildAt(i));
|
||||
}
|
||||
super.removeViewsInLayout(start, count);
|
||||
invalidateCache();
|
||||
mChildren.removeViewsInLayout(start, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestChildFocus(View child, View focused) {
|
||||
super.requestChildFocus(child, focused);
|
||||
if (child != null) {
|
||||
Rect r = new Rect();
|
||||
child.getDrawingRect(r);
|
||||
requestRectangleOnScreen(r);
|
||||
}
|
||||
public void drawChildren(Canvas canvas) {
|
||||
mChildren.draw(canvas);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -716,11 +587,11 @@ public class CellLayout extends ViewGroup implements VisibilityChangedListener {
|
||||
final Rect frame = mRect;
|
||||
final int x = touchX + mScrollX;
|
||||
final int y = touchY + mScrollY;
|
||||
final int count = getChildCount();
|
||||
final int count = mChildren.getChildCount();
|
||||
|
||||
boolean found = false;
|
||||
for (int i = count - 1; i >= 0; i--) {
|
||||
final View child = getChildAt(i);
|
||||
final View child = mChildren.getChildAt(i);
|
||||
|
||||
if ((child.getVisibility()) == VISIBLE || child.getAnimation() != null) {
|
||||
child.getHitRect(frame);
|
||||
@@ -753,7 +624,6 @@ public class CellLayout extends ViewGroup implements VisibilityChangedListener {
|
||||
setTag(cellInfo);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
if (mInterceptTouchListener != null && mInterceptTouchListener.onTouch(this, ev)) {
|
||||
@@ -886,68 +756,35 @@ public class CellLayout extends ViewGroup implements VisibilityChangedListener {
|
||||
mWidthGap = mHeightGap = minGap;
|
||||
}
|
||||
|
||||
int count = getChildCount();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
View child = getChildAt(i);
|
||||
LayoutParams lp = (LayoutParams) child.getLayoutParams();
|
||||
lp.setup(cellWidth, cellHeight, mWidthGap, mHeightGap,
|
||||
mLeftPadding, mTopPadding);
|
||||
|
||||
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
|
||||
int childheightMeasureSpec = MeasureSpec.makeMeasureSpec(lp.height,
|
||||
MeasureSpec.EXACTLY);
|
||||
|
||||
child.measure(childWidthMeasureSpec, childheightMeasureSpec);
|
||||
}
|
||||
// Initial values correspond to widthSpecMode == MeasureSpec.EXACTLY
|
||||
int newWidth = widthSpecSize;
|
||||
int newHeight = heightSpecSize;
|
||||
if (widthSpecMode == MeasureSpec.AT_MOST) {
|
||||
int newWidth = mLeftPadding + mRightPadding + (mCountX * cellWidth) +
|
||||
newWidth = mLeftPadding + mRightPadding + (mCountX * cellWidth) +
|
||||
((mCountX - 1) * mWidthGap);
|
||||
int newHeight = mTopPadding + mBottomPadding + (mCountY * cellHeight) +
|
||||
newHeight = mTopPadding + mBottomPadding + (mCountY * cellHeight) +
|
||||
((mCountY - 1) * mHeightGap);
|
||||
setMeasuredDimension(newWidth, newHeight);
|
||||
} else if (widthSpecMode == MeasureSpec.EXACTLY) {
|
||||
setMeasuredDimension(widthSpecSize, heightSpecSize);
|
||||
}
|
||||
|
||||
int count = getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
View child = getChildAt(i);
|
||||
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(newWidth, MeasureSpec.EXACTLY);
|
||||
int childheightMeasureSpec = MeasureSpec.makeMeasureSpec(newHeight,
|
||||
MeasureSpec.EXACTLY);
|
||||
child.measure(childWidthMeasureSpec, childheightMeasureSpec);
|
||||
}
|
||||
setMeasuredDimension(newWidth, newHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
int count = getChildCount();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
final View child = getChildAt(i);
|
||||
if (child.getVisibility() != GONE) {
|
||||
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
|
||||
|
||||
int childLeft = lp.x;
|
||||
int childTop = lp.y;
|
||||
child.layout(childLeft, childTop, childLeft + lp.width, childTop + lp.height);
|
||||
|
||||
if (lp.dropped) {
|
||||
lp.dropped = false;
|
||||
|
||||
final int[] cellXY = mTmpCellXY;
|
||||
getLocationOnScreen(cellXY);
|
||||
mWallpaperManager.sendWallpaperCommand(getWindowToken(),
|
||||
WallpaperManager.COMMAND_DROP,
|
||||
cellXY[0] + childLeft + lp.width / 2,
|
||||
cellXY[1] + childTop + lp.height / 2, 0, null);
|
||||
|
||||
if (lp.animateDrop) {
|
||||
lp.animateDrop = false;
|
||||
|
||||
// This call does not result in a requestLayout(), but at one point did.
|
||||
// We need to be cautious about any method calls within the layout pass
|
||||
// to insure we don't leave the view tree in a bad state.
|
||||
((Workspace) mParent).animateViewIntoPosition(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
View child = getChildAt(i);
|
||||
child.layout(0, 0, r - l, b - t);
|
||||
}
|
||||
prepareCacheBitmap();
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -955,28 +792,16 @@ public class CellLayout extends ViewGroup implements VisibilityChangedListener {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
mBackgroundRect.set(0, 0, w, h);
|
||||
updateGlowRect();
|
||||
mCacheRect.set(0, 0, (int) (mBitmapCacheScale * w), (int) (mBitmapCacheScale * h));
|
||||
mCache = null;
|
||||
prepareCacheBitmap();
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setChildrenDrawingCacheEnabled(boolean enabled) {
|
||||
final int count = getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
final View view = getChildAt(i);
|
||||
view.setDrawingCacheEnabled(enabled);
|
||||
// Update the drawing caches
|
||||
if (!view.isHardwareAccelerated()) {
|
||||
view.buildDrawingCache(true);
|
||||
}
|
||||
}
|
||||
mChildren.setChildrenDrawingCacheEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setChildrenDrawnWithCacheEnabled(boolean enabled) {
|
||||
super.setChildrenDrawnWithCacheEnabled(enabled);
|
||||
mChildren.setChildrenDrawnWithCacheEnabled(enabled);
|
||||
}
|
||||
|
||||
public float getBackgroundAlpha() {
|
||||
@@ -1017,17 +842,7 @@ public class CellLayout extends ViewGroup implements VisibilityChangedListener {
|
||||
}
|
||||
|
||||
public View getChildAt(int x, int y) {
|
||||
final int count = getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
View child = getChildAt(i);
|
||||
LayoutParams lp = (LayoutParams) child.getLayoutParams();
|
||||
|
||||
if ((lp.cellX <= x) && (x < lp.cellX + lp.cellHSpan) &&
|
||||
(lp.cellY <= y) && (y < lp.cellY + lp.cellHSpan)) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return mChildren.getChildAt(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1506,13 +1321,13 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
|
||||
}
|
||||
|
||||
private void markCellsAsOccupiedForView(View view) {
|
||||
if (view == null || view.getParent() != this) return;
|
||||
if (view == null || view.getParent() != mChildren) return;
|
||||
LayoutParams lp = (LayoutParams) view.getLayoutParams();
|
||||
markCellsForView(lp.cellX, lp.cellY, lp.cellHSpan, lp.cellVSpan, true);
|
||||
}
|
||||
|
||||
private void markCellsAsUnoccupiedForView(View view) {
|
||||
if (view == null || view.getParent() != this) return;
|
||||
if (view == null || view.getParent() != mChildren) return;
|
||||
LayoutParams lp = (LayoutParams) view.getLayoutParams();
|
||||
markCellsForView(lp.cellX, lp.cellY, lp.cellHSpan, lp.cellVSpan, false);
|
||||
}
|
||||
@@ -1676,14 +1491,3 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Custom interfaces used to listen to "visibility changed" events of *children* of Views. Avoided
|
||||
// using "onVisibilityChanged" in the names because there's a method of that name in framework
|
||||
// (which can only can be used to listen to ancestors' "visibility changed" events)
|
||||
interface VisibilityChangedBroadcaster {
|
||||
public void setVisibilityChangedListener(VisibilityChangedListener listener);
|
||||
}
|
||||
|
||||
interface VisibilityChangedListener {
|
||||
public void receiveVisibilityChangedMessage(View v);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.launcher2;
|
||||
|
||||
import android.app.WallpaperManager;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.view.View;
|
||||
|
||||
public class CellLayoutChildren extends CachedViewGroup {
|
||||
static final String TAG = "CellLayoutChildren";
|
||||
|
||||
// These are temporary variables to prevent having to allocate a new object just to
|
||||
// return an (x, y) value from helper functions. Do NOT use them to maintain other state.
|
||||
private final int[] mTmpCellXY = new int[2];
|
||||
|
||||
private final WallpaperManager mWallpaperManager;
|
||||
|
||||
private int mCellWidth;
|
||||
private int mCellHeight;
|
||||
|
||||
private int mLeftPadding;
|
||||
private int mTopPadding;
|
||||
|
||||
private int mWidthGap;
|
||||
private int mHeightGap;
|
||||
|
||||
public CellLayoutChildren(Context context) {
|
||||
super(context);
|
||||
mWallpaperManager = WallpaperManager.getInstance(context);
|
||||
}
|
||||
|
||||
public void setCellDimensions(int cellWidth, int cellHeight,
|
||||
int leftPadding, int topPadding, int widthGap, int heightGap ) {
|
||||
mCellWidth = cellWidth;
|
||||
mCellHeight = cellHeight;
|
||||
mLeftPadding = leftPadding;
|
||||
mTopPadding = topPadding;
|
||||
mWidthGap = widthGap;
|
||||
mHeightGap = heightGap;
|
||||
}
|
||||
|
||||
public View getChildAt(int x, int y) {
|
||||
final int count = getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
View child = getChildAt(i);
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
|
||||
|
||||
if ((lp.cellX <= x) && (x < lp.cellX + lp.cellHSpan) &&
|
||||
(lp.cellY <= y) && (y < lp.cellY + lp.cellHSpan)) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
final int cellWidth = mCellWidth;
|
||||
final int cellHeight = mCellHeight;
|
||||
int count = getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
View child = getChildAt(i);
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
|
||||
|
||||
lp.setup(cellWidth, cellHeight, mWidthGap, mHeightGap,
|
||||
mLeftPadding, mTopPadding);
|
||||
|
||||
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
|
||||
int childheightMeasureSpec = MeasureSpec.makeMeasureSpec(lp.height,
|
||||
MeasureSpec.EXACTLY);
|
||||
|
||||
child.measure(childWidthMeasureSpec, childheightMeasureSpec);
|
||||
}
|
||||
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
|
||||
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
|
||||
setMeasuredDimension(widthSpecSize, heightSpecSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
super.onLayout(changed, l, t, r, b);
|
||||
int count = getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
final View child = getChildAt(i);
|
||||
if (child.getVisibility() != GONE) {
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
|
||||
|
||||
int childLeft = lp.x;
|
||||
int childTop = lp.y;
|
||||
child.layout(childLeft, childTop, childLeft + lp.width, childTop + lp.height);
|
||||
|
||||
if (lp.dropped) {
|
||||
lp.dropped = false;
|
||||
|
||||
final int[] cellXY = mTmpCellXY;
|
||||
getLocationOnScreen(cellXY);
|
||||
mWallpaperManager.sendWallpaperCommand(getWindowToken(),
|
||||
WallpaperManager.COMMAND_DROP,
|
||||
cellXY[0] + childLeft + lp.width / 2,
|
||||
cellXY[1] + childTop + lp.height / 2, 0, null);
|
||||
|
||||
if (lp.animateDrop) {
|
||||
lp.animateDrop = false;
|
||||
|
||||
// This call does not result in a requestLayout(), but at one point did.
|
||||
// We need to be cautious about any method calls within the layout pass
|
||||
// to insure we don't leave the view tree in a bad state.
|
||||
((Workspace) mParent.getParent()).animateViewIntoPosition(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestChildFocus(View child, View focused) {
|
||||
super.requestChildFocus(child, focused);
|
||||
if (child != null) {
|
||||
Rect r = new Rect();
|
||||
child.getDrawingRect(r);
|
||||
requestRectangleOnScreen(r);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelLongPress() {
|
||||
super.cancelLongPress();
|
||||
|
||||
// Cancel long press for all children
|
||||
final int count = getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
final View child = getChildAt(i);
|
||||
child.cancelLongPress();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setChildrenDrawingCacheEnabled(boolean enabled) {
|
||||
final int count = getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
final View view = getChildAt(i);
|
||||
view.setDrawingCacheEnabled(enabled);
|
||||
// Update the drawing caches
|
||||
if (!view.isHardwareAccelerated()) {
|
||||
view.buildDrawingCache(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setChildrenDrawnWithCacheEnabled(boolean enabled) {
|
||||
super.setChildrenDrawnWithCacheEnabled(enabled);
|
||||
}
|
||||
}
|
||||
@@ -1963,7 +1963,7 @@ public final class Launcher extends Activity
|
||||
|
||||
void closeFolder(Folder folder) {
|
||||
folder.getInfo().opened = false;
|
||||
ViewGroup parent = (ViewGroup) folder.getParent();
|
||||
ViewGroup parent = (ViewGroup) folder.getParent().getParent();
|
||||
if (parent != null) {
|
||||
CellLayout cl = (CellLayout) parent;
|
||||
cl.removeViewWithoutMarkingCells(folder);
|
||||
@@ -2212,7 +2212,7 @@ public final class Launcher extends Activity
|
||||
}
|
||||
|
||||
if (!(v instanceof CellLayout)) {
|
||||
v = (View) v.getParent();
|
||||
v = (View) v.getParent().getParent();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ public abstract class PagedView extends ViewGroup {
|
||||
protected boolean mAllowOverScroll = true;
|
||||
protected int mUnboundedScrollX;
|
||||
|
||||
// parameter that adjusts the layout to be optimized for CellLayouts with that scale factor
|
||||
// parameter that adjusts the layout to be optimized for pages with that scale factor
|
||||
protected float mLayoutScale = 1.0f;
|
||||
|
||||
protected static final int INVALID_POINTER = -1;
|
||||
@@ -416,20 +416,20 @@ public abstract class PagedView extends ViewGroup {
|
||||
setMeasuredDimension(widthSize, heightSize);
|
||||
}
|
||||
|
||||
protected void moveToNewPageWithoutMovingCellLayouts(int newCurrentPage) {
|
||||
protected void scrollToNewPageWithoutMovingPages(int newCurrentPage) {
|
||||
int newX = getChildOffset(newCurrentPage) - getRelativeChildOffset(newCurrentPage);
|
||||
int delta = newX - mScrollX;
|
||||
|
||||
final int screenCount = getChildCount();
|
||||
for (int i = 0; i < screenCount; i++) {
|
||||
CellLayout cl = (CellLayout) getChildAt(i);
|
||||
cl.setX(cl.getX() + delta);
|
||||
final int pageCount = getChildCount();
|
||||
for (int i = 0; i < pageCount; i++) {
|
||||
View page = (View) getChildAt(i);
|
||||
page.setX(page.getX() + delta);
|
||||
}
|
||||
setCurrentPage(newCurrentPage);
|
||||
}
|
||||
|
||||
// A layout scale of 1.0f assumes that the CellLayouts, in their unshrunken state, have a
|
||||
// scale of 1.0f. A layout scale of 0.8f assumes the CellLayouts have a scale of 0.8f, and
|
||||
// A layout scale of 1.0f assumes that the pages, in their unshrunken state, have a
|
||||
// scale of 1.0f. A layout scale of 0.8f assumes the pages have a scale of 0.8f, and
|
||||
// tightens the layout accordingly
|
||||
public void setLayoutScale(float childrenScale) {
|
||||
mLayoutScale = childrenScale;
|
||||
@@ -451,7 +451,7 @@ public abstract class PagedView extends ViewGroup {
|
||||
}
|
||||
// Also, the page offset has changed (since the pages are now smaller);
|
||||
// update the page offset, but again preserving absolute X and Y coordinates
|
||||
moveToNewPageWithoutMovingCellLayouts(mCurrentPage);
|
||||
scrollToNewPageWithoutMovingPages(mCurrentPage);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1519,7 +1519,7 @@ public class Workspace extends SmoothPagedView
|
||||
if (springLoaded) {
|
||||
setLayoutScale(SPRING_LOADED_DRAG_SHRINK_FACTOR);
|
||||
}
|
||||
moveToNewPageWithoutMovingCellLayouts(newCurrentPage);
|
||||
scrollToNewPageWithoutMovingPages(newCurrentPage);
|
||||
unshrink(true, springLoaded);
|
||||
}
|
||||
}
|
||||
@@ -1811,7 +1811,7 @@ public class Workspace extends SmoothPagedView
|
||||
* calls, as it is called from onLayout().
|
||||
*/
|
||||
public void animateViewIntoPosition(final View view) {
|
||||
final CellLayout parent = (CellLayout) view.getParent();
|
||||
final CellLayout parent = (CellLayout) view.getParent().getParent();
|
||||
final CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams();
|
||||
|
||||
// Convert the animation params to be relative to the Workspace, not the CellLayout
|
||||
@@ -1918,7 +1918,7 @@ public class Workspace extends SmoothPagedView
|
||||
// subsequent taps add items to that screen
|
||||
int dragTargetIndex = indexOfChild(mDragTargetLayout);
|
||||
if (mCurrentPage != dragTargetIndex && (mIsSmall || mIsInUnshrinkAnimation)) {
|
||||
moveToNewPageWithoutMovingCellLayouts(dragTargetIndex);
|
||||
scrollToNewPageWithoutMovingPages(dragTargetIndex);
|
||||
}
|
||||
|
||||
if (source != this) {
|
||||
@@ -1979,7 +1979,7 @@ public class Workspace extends SmoothPagedView
|
||||
}
|
||||
}
|
||||
|
||||
final CellLayout parent = (CellLayout) cell.getParent();
|
||||
final CellLayout parent = (CellLayout) cell.getParent().getParent();
|
||||
|
||||
// Prepare it to be animated into its new position
|
||||
// This must be called after the view has been re-parented
|
||||
|
||||
Reference in New Issue
Block a user