summaryrefslogtreecommitdiffstats
path: root/src/com
diff options
context:
space:
mode:
authorMichael Jurka <mikejurka@google.com>2011-01-20 14:16:56 -0800
committerMichael Jurka <mikejurka@google.com>2011-01-24 16:55:30 -0800
commit8c920dd3683d752aa4c43e964831ce53f9b72887 (patch)
tree35faeed05b46a1e0b1c9ab0b35f57fb997913a72 /src/com
parentadabb50e55f202e73576d2c268ae681c2bc5a822 (diff)
downloadandroid_packages_apps_Trebuchet-8c920dd3683d752aa4c43e964831ce53f9b72887.tar.gz
android_packages_apps_Trebuchet-8c920dd3683d752aa4c43e964831ce53f9b72887.tar.bz2
android_packages_apps_Trebuchet-8c920dd3683d752aa4c43e964831ce53f9b72887.zip
Refactoring CellLayout into three classes
- splitting the rendering of children from the CellLayout to enhance performance, gives ~4 fps boost while scrolling on pages full of icons, and no change on pages full of widgets - this will allow us to add hardware layer support trivially, which will increase performance while scrolling ~6-10 fps - separated logic for caching celllayouts to bitmaps into a separate class Change-Id: Ib6abeb19126e1504997b43c2f44af2a2fb3cd39f
Diffstat (limited to 'src/com')
-rw-r--r--src/com/android/launcher2/CachedViewGroup.java258
-rw-r--r--src/com/android/launcher2/CellLayout.java286
-rw-r--r--src/com/android/launcher2/CellLayoutChildren.java170
-rw-r--r--src/com/android/launcher2/Launcher.java4
-rw-r--r--src/com/android/launcher2/PagedView.java18
-rw-r--r--src/com/android/launcher2/Workspace.java8
6 files changed, 488 insertions, 256 deletions
diff --git a/src/com/android/launcher2/CachedViewGroup.java b/src/com/android/launcher2/CachedViewGroup.java
new file mode 100644
index 000000000..b5cfd6062
--- /dev/null
+++ b/src/com/android/launcher2/CachedViewGroup.java
@@ -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);
+} \ No newline at end of file
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index 49ae65290..9c629eef9 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -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();
+ // Initial values correspond to widthSpecMode == MeasureSpec.EXACTLY
+ int newWidth = widthSpecSize;
+ int newHeight = heightSpecSize;
+ if (widthSpecMode == MeasureSpec.AT_MOST) {
+ newWidth = mLeftPadding + mRightPadding + (mCountX * cellWidth) +
+ ((mCountX - 1) * mWidthGap);
+ newHeight = mTopPadding + mBottomPadding + (mCountY * cellHeight) +
+ ((mCountY - 1) * mHeightGap);
+ setMeasuredDimension(newWidth, newHeight);
+ }
+ 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,
+ int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(newWidth, MeasureSpec.EXACTLY);
+ int childheightMeasureSpec = MeasureSpec.makeMeasureSpec(newHeight,
MeasureSpec.EXACTLY);
-
child.measure(childWidthMeasureSpec, childheightMeasureSpec);
}
- if (widthSpecMode == MeasureSpec.AT_MOST) {
- int newWidth = mLeftPadding + mRightPadding + (mCountX * cellWidth) +
- ((mCountX - 1) * mWidthGap);
- int newHeight = mTopPadding + mBottomPadding + (mCountY * cellHeight) +
- ((mCountY - 1) * mHeightGap);
- setMeasuredDimension(newWidth, newHeight);
- } else if (widthSpecMode == MeasureSpec.EXACTLY) {
- setMeasuredDimension(widthSpecSize, heightSpecSize);
- }
+ 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);
-}
diff --git a/src/com/android/launcher2/CellLayoutChildren.java b/src/com/android/launcher2/CellLayoutChildren.java
new file mode 100644
index 000000000..09ab26688
--- /dev/null
+++ b/src/com/android/launcher2/CellLayoutChildren.java
@@ -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);
+ }
+} \ No newline at end of file
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index f381b1fe2..dabc42a9e 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -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();
}
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index 4a0f44e2c..d99921f9f 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -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
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index b9a2b6234..e7fb0fde4 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -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