diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/launcher2/CachedViewGroup.java | 258 | ||||
-rw-r--r-- | src/com/android/launcher2/CellLayout.java | 286 | ||||
-rw-r--r-- | src/com/android/launcher2/CellLayoutChildren.java | 170 | ||||
-rw-r--r-- | src/com/android/launcher2/Launcher.java | 4 | ||||
-rw-r--r-- | src/com/android/launcher2/PagedView.java | 18 | ||||
-rw-r--r-- | src/com/android/launcher2/Workspace.java | 8 |
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 0000000..b5cfd60 --- /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 49ae652..9c629ee 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 0000000..09ab266 --- /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 f381b1f..dabc42a 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 4a0f44e..d99921f 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 b9a2b62..e7fb0fd 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 |