diff options
-rw-r--r-- | res/raw/rollo.c | 86 | ||||
-rw-r--r-- | src/com/android/launcher2/AllAppsView.java | 269 | ||||
-rw-r--r-- | src/com/android/launcher2/AppInfoCache.java | 5 | ||||
-rw-r--r-- | src/com/android/launcher2/ApplicationsAdapter.java | 2 | ||||
-rw-r--r-- | src/com/android/launcher2/FolderIcon.java | 2 | ||||
-rw-r--r-- | src/com/android/launcher2/Launcher.java | 4 | ||||
-rw-r--r-- | src/com/android/launcher2/LauncherModel.java | 5 | ||||
-rw-r--r-- | src/com/android/launcher2/LiveFolderAdapter.java | 3 | ||||
-rw-r--r-- | src/com/android/launcher2/LiveFolderIcon.java | 2 | ||||
-rw-r--r-- | src/com/android/launcher2/Utilities.java | 116 | ||||
-rw-r--r-- | src/com/android/launcher2/Workspace.java | 2 |
11 files changed, 366 insertions, 130 deletions
diff --git a/res/raw/rollo.c b/res/raw/rollo.c index f6097cf12..028d537f9 100644 --- a/res/raw/rollo.c +++ b/res/raw/rollo.c @@ -29,30 +29,14 @@ #define STATE_FLING_DURATION 6 #define STATE_FLING_END_POS 7 -#define SCROLL_HANDLE_POS 8 +#define STATE_START_SCROLL_X 8 +#define STATE_SELECTED_ICON_INDEX 9 +#define STATE_SELECTED_ICON_TEXTURE 10 -// Scratch variables ====== -#define SCRATCH_ADJUSTED_DECELERATION 0 +#define STATE_BORDERY0 11 // Drawing constants, should be parameters ====== -#define SCREEN_WIDTH_PX 480 -#define SCREEN_HEIGHT 854 - -#define PAGE_PADDING_TOP_PX 80 -#define CELL_PADDING_TOP_PX 5 -#define ICON_HEIGHT_PX 64 -#define ICON_TEXTURE_HEIGHT_PX 128 -#define ICON_LABEL_GUTTER_PX 5 -#define CELL_PADDING_BOTTOM_PX 5 -#define ROW_GUTTER_PX 10 - -#define PAGE_PADDING_LEFT_PX 22 -#define CELL_WIDTH_PX 105 -#define ICON_WIDTH_PX 64 -#define ICON_TEXTURE_WIDTH_PX 128 - #define VIEW_ANGLE 1.28700222f -#define RADIUS 4.0f int count_pages(int iconCount) @@ -89,9 +73,11 @@ draw_page(int icon, int lastIcon, float centerAngle) float iconWidthAngle = VIEW_ANGLE * ICON_WIDTH_PX / SCREEN_WIDTH_PX; float columnGutterAngle = iconWidthAngle * 0.70f; - float farIconSize = far_size(2 * ICON_WIDTH_PX / (float)SCREEN_WIDTH_PX); + float farIconSize = FAR_ICON_SIZE; float iconGutterHeight = farIconSize * 1.1f; + float farIconTextureSize = far_size(2 * ICON_TEXTURE_WIDTH_PX / (float)SCREEN_WIDTH_PX); + float labelWidthPx = loadI32(ALLOC_PARAMS, PARAM_BUBBLE_WIDTH); float labelHeightPx = loadI32(ALLOC_PARAMS, PARAM_BUBBLE_HEIGHT); @@ -101,18 +87,22 @@ draw_page(int icon, int lastIcon, float centerAngle) float labelTextureWidth = labelWidthPx / loadI32(ALLOC_PARAMS, PARAM_BUBBLE_BITMAP_WIDTH); float labelTextureHeight = labelHeightPx / loadI32(ALLOC_PARAMS, PARAM_BUBBLE_BITMAP_HEIGHT); + int selectedIconIndex = loadI32(ALLOC_STATE, STATE_SELECTED_ICON_INDEX); for (row=0; row<ROWS_PER_PAGE && icon<=lastIcon; row++) { float angle = centerAngle; angle -= (columnGutterAngle + iconWidthAngle) * 1.5f; - float iconTop = (farIconSize + iconGutterHeight) * 2.2f + float iconTop = (farIconSize + iconGutterHeight) * (2.0f + ICON_TOP_OFFSET) - row * (farIconSize + iconGutterHeight); float iconBottom = iconTop - farIconSize; float labelTop = iconBottom - (.1 * farLabelHeight); float labelBottom = labelTop - farLabelHeight; + float iconTextureTop = iconTop + (0.5f * (farIconTextureSize - farIconSize)); + float iconTextureBottom = iconTextureTop - farIconTextureSize; + for (col=0; col<COLUMNS_PER_PAGE && icon<=lastIcon; col++) { // icon float sine = sinf(angle); @@ -121,17 +111,26 @@ draw_page(int icon, int lastIcon, float centerAngle) float centerX = sine * RADIUS; float centerZ = cosine * RADIUS; - float iconLeftX = centerX - (cosine * farIconSize * .5); - float iconRightX = centerX + (cosine * farIconSize * .5); - float iconLeftZ = centerZ + (sine * farIconSize * .5); - float iconRightZ = centerZ - (sine * farIconSize * .5); + float iconLeftX = centerX - (cosine * farIconTextureSize * .5); + float iconRightX = centerX + (cosine * farIconTextureSize * .5); + float iconLeftZ = centerZ + (sine * farIconTextureSize * .5); + float iconRightZ = centerZ - (sine * farIconTextureSize * .5); + + if (selectedIconIndex == icon) { + bindTexture(NAMED_PF, 0, loadI32(ALLOC_STATE, STATE_SELECTED_ICON_TEXTURE)); + drawQuadTexCoords( + iconLeftX, iconTextureTop, iconLeftZ, 0.0f, 0.0f, + iconRightX, iconTextureTop, iconRightZ, 1.0f, 0.0f, + iconRightX, iconTextureBottom, iconRightZ, 1.0f, 1.0f, + iconLeftX, iconTextureBottom, iconLeftZ, 0.0f, 1.0f); + } bindTexture(NAMED_PF, 0, loadI32(ALLOC_ICON_IDS, icon)); drawQuadTexCoords( - iconLeftX, iconTop, iconLeftZ, 0.0f, 0.0f, - iconRightX, iconTop, iconRightZ, iconTextureWidth, 0.0f, - iconRightX, iconBottom, iconRightZ, iconTextureWidth, iconTextureHeight, - iconLeftX, iconBottom, iconLeftZ, 0.0f, iconTextureHeight); + iconLeftX, iconTextureTop, iconLeftZ, 0.0f, 0.0f, + iconRightX, iconTextureTop, iconRightZ, 1.0f, 0.0f, + iconRightX, iconTextureBottom, iconRightZ, 1.0f, 1.0f, + iconLeftX, iconTextureBottom, iconLeftZ, 0.0f, 1.0f); // label float labelLeftX = centerX - farLabelWidth * 0.5f; @@ -160,17 +159,6 @@ main(int launchID) int iconCount = loadI32(ALLOC_STATE, STATE_ICON_COUNT); int pageCount = count_pages(iconCount); - float densityScale = 2.0f / SCREEN_WIDTH_PX; - float screenTop = SCREEN_HEIGHT/(float)SCREEN_WIDTH_PX; // == (SCREEN_HEIGHT/2)*densityScale; - - float pagePaddingTop = screenTop - (PAGE_PADDING_TOP_PX * densityScale); - float pageGutterY = ROW_GUTTER_PX * densityScale; - float cellHeight = (CELL_PADDING_TOP_PX + ICON_HEIGHT_PX + ICON_LABEL_GUTTER_PX - + loadI32(ALLOC_PARAMS, PARAM_BUBBLE_HEIGHT) - + CELL_PADDING_BOTTOM_PX + ROW_GUTTER_PX) * densityScale; - float cellPaddingTop = CELL_PADDING_TOP_PX * densityScale; - float iconLabelGutter = ICON_LABEL_GUTTER_PX * densityScale; - float scrollXPx = loadI32(ALLOC_STATE, STATE_SCROLL_X); float maxScrollXPx = -(pageCount-1) * SCREEN_WIDTH_PX; int done = 0; @@ -313,12 +301,26 @@ main(int launchID) draw_page(icon, lastIcon, -VIEW_ANGLE*currentPagePosition); draw_page(icon+iconsPerPage, lastIcon, (-VIEW_ANGLE*currentPagePosition)+VIEW_ANGLE); - // Draw the scroll handle ======================================== + // Draw the border lines for debugging ======================================== /* bindProgramVertex(NAMED_PVOrtho); bindProgramFragment(NAMED_PFText); bindProgramFragmentStore(NAMED_PFSText); + color(1.0f, 1.0f, 0.0f, 0.99f); + int i; + for (i=0; i<ROWS_PER_PAGE+1; i++) { + int y = loadI32(ALLOC_Y_BORDERS, i); + drawRect(0, y, SCREEN_WIDTH_PX, y+1, 0.0f); + } + for (i=0; i<COLUMNS_PER_PAGE+1; i++) { + int x = loadI32(ALLOC_X_BORDERS, i); + drawRect(x, 0, x+1, SCREEN_HEIGHT_PX, 0.0f); + } + */ + + // Draw the scroll handle ======================================== + /* bindTexture(NAMED_PFText, 0, loadI32(ALLOC_PARAMS, PARAM_SCROLL_HANDLE_ID)); float handleLeft = 40 + (320 * (scrollXPx/(float)(maxScrollXPx))); float handleTop = 680; diff --git a/src/com/android/launcher2/AllAppsView.java b/src/com/android/launcher2/AllAppsView.java index d8ac50b48..b9ec2cfb3 100644 --- a/src/com/android/launcher2/AllAppsView.java +++ b/src/com/android/launcher2/AllAppsView.java @@ -39,6 +39,7 @@ import android.content.res.Resources; import android.database.DataSetObserver; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.BlurMaskFilter; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.drawable.BitmapDrawable; @@ -53,37 +54,61 @@ import android.view.MotionEvent; import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceView; +import android.view.View; import android.view.VelocityTracker; import android.view.ViewConfiguration; import android.graphics.PixelFormat; -public class AllAppsView extends RSSurfaceView { +public class AllAppsView extends RSSurfaceView + implements View.OnClickListener, View.OnLongClickListener { private static final String TAG = "Launcher.AllAppsView"; + private Launcher mLauncher; + private RenderScript mRS; private RolloRS mRollo; private ArrayList<ApplicationInfo> mAllAppsList; private ViewConfiguration mConfig; private int mPageCount; + private boolean mStartedScrolling; private VelocityTracker mVelocity; private int mLastScrollX; private int mLastMotionX; - private ApplicationsAdapter mAdapter; private TouchHandler mTouchHandler; private int mScrollHandleTop; - class Defines { + static class Defines { + private static float farSize(float sizeAt0) { + return sizeAt0 * (Defines.RADIUS - Defines.CAMERA_Z) / -Defines.CAMERA_Z; + } + public static final int ALLOC_PARAMS = 0; public static final int ALLOC_STATE = 1; - public static final int ALLOC_SCRATCH = 2; - public static final int ALLOC_ICON_IDS = 3; - public static final int ALLOC_LABEL_IDS = 4; + public static final int ALLOC_ICON_IDS = 2; + public static final int ALLOC_LABEL_IDS = 3; + public static final int ALLOC_X_BORDERS = 4; + public static final int ALLOC_Y_BORDERS = 5; public static final int COLUMNS_PER_PAGE = 4; public static final int ROWS_PER_PAGE = 4; + public static final float RADIUS = 4.0f; + + public static final int SCREEN_WIDTH_PX = 480; + public static final int SCREEN_HEIGHT_PX = 854; + + public static final int ICON_WIDTH_PX = 64; + public static final int ICON_TEXTURE_WIDTH_PX = 128; + + public static final int ICON_HEIGHT_PX = 64; + public static final int ICON_TEXTURE_HEIGHT_PX = 128; + public static final float ICON_TOP_OFFSET = 0.2f; + + public static final float CAMERA_Z = -2; + public static final float FAR_ICON_SIZE + = farSize(2 * ICON_WIDTH_PX / (float)SCREEN_WIDTH_PX); } public AllAppsView(Context context, AttributeSet attrs) { @@ -91,36 +116,38 @@ public class AllAppsView extends RSSurfaceView { setFocusable(true); getHolder().setFormat(PixelFormat.TRANSLUCENT); mConfig = ViewConfiguration.get(context); + setOnClickListener(this); + setOnLongClickListener(this); } public AllAppsView(Context context, AttributeSet attrs, int defStyle) { this(context, attrs); } - void setAdapter(ApplicationsAdapter adapter) { - if (mAdapter != null) { - mAdapter.unregisterDataSetObserver(mIconObserver); - } - mAdapter = adapter; - if (adapter != null) { - adapter.registerDataSetObserver(mIconObserver); - } + public void setLauncher(Launcher launcher) { + mLauncher = launcher; } @Override public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { super.surfaceChanged(holder, format, w, h); + long startTime = SystemClock.uptimeMillis(); + mRS = createRenderScript(true); mRollo = new RolloRS(); mRollo.init(getResources(), w, h); if (mAllAppsList != null) { mRollo.setApps(mAllAppsList); + Log.d(TAG, "surfaceChanged... calling mRollo.setApps"); } Resources res = getContext().getResources(); int barHeight = (int)res.getDimension(R.dimen.button_bar_height); mScrollHandleTop = h - barHeight; + + long endTime = SystemClock.uptimeMillis(); + Log.d(TAG, "surfaceChanged took " + (endTime-startTime) + "ms"); } @Override @@ -133,6 +160,8 @@ public class AllAppsView extends RSSurfaceView { @Override public boolean onTouchEvent(MotionEvent ev) { + super.onTouchEvent(ev); + mTouchHandler = mFlingHandler; /* int action = ev.getAction(); @@ -144,7 +173,9 @@ public class AllAppsView extends RSSurfaceView { } } */ - return mTouchHandler.onTouchEvent(ev); + mTouchHandler.onTouchEvent(ev); + + return true; } private abstract class TouchHandler { @@ -161,22 +192,38 @@ public class AllAppsView extends RSSurfaceView { case MotionEvent.ACTION_DOWN: mLastMotionX = x; mRollo.mState.read(); - mRollo.mState.scrollX = mLastScrollX = mRollo.mState.currentScrollX; + mRollo.mState.startScrollX = mRollo.mState.scrollX = mLastScrollX + = mRollo.mState.currentScrollX; + if (mRollo.mState.flingVelocityX != 0) { + mRollo.clearSelectedIcon(); + } else { + mRollo.selectIcon(x, (int)ev.getY(), mRollo.mState.startScrollX, + (-mRollo.mState.startScrollX / Defines.SCREEN_WIDTH_PX)); + } mRollo.mState.flingVelocityX = 0; mRollo.mState.adjustedDeceleration = 0; mRollo.mState.save(); mVelocity = VelocityTracker.obtain(); mVelocity.addMovement(ev); + mStartedScrolling = false; break; case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_OUTSIDE: - deltaX = x - mLastMotionX; - mVelocity.addMovement(ev); - mRollo.mState.currentScrollX = mLastScrollX; - mLastScrollX += deltaX; - mRollo.mState.scrollX = mLastScrollX; - mRollo.mState.save(); - mLastMotionX = x; + int slop = Math.abs(x - mLastMotionX); + if (!mStartedScrolling && slop < mConfig.getScaledTouchSlop()) { + // don't update mLastMotionX so slop is right and when we do start scrolling + // below, we get the right delta. + } else { + mStartedScrolling = true; + mRollo.clearSelectedIcon(); + deltaX = x - mLastMotionX; + mVelocity.addMovement(ev); + mRollo.mState.currentScrollX = mLastScrollX; + mLastScrollX += deltaX; + mRollo.mState.scrollX = mLastScrollX; + mRollo.mState.save(); + mLastMotionX = x; + } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: @@ -184,6 +231,7 @@ public class AllAppsView extends RSSurfaceView { mConfig.getScaledMaximumFlingVelocity()); mRollo.mState.flingTimeMs = (int)SystemClock.uptimeMillis(); // TODO: use long mRollo.mState.flingVelocityX = (int)mVelocity.getXVelocity(); + mRollo.clearSelectedIcon(); mRollo.mState.save(); mLastMotionX = -10000; mVelocity.recycle(); @@ -194,6 +242,20 @@ public class AllAppsView extends RSSurfaceView { } }; + public void onClick(View v) { + int index = mRollo.mState.selectedIconIndex; + if (mRollo.mState.flingVelocityX == 0 && index >= 0 && index < mAllAppsList.size()) { + ApplicationInfo app = mAllAppsList.get(index); + mLauncher.startActivitySafely(app.intent); + } + } + + public boolean onLongClick(View v) { + Log.d(TAG, "long click! velocity=" + mRollo.mState.flingVelocityX + " index=" + + mRollo.mState.selectedIconIndex); + return true; + } + /* private TouchHandler mScrollHandler = new TouchHandler() { @Override @@ -229,18 +291,17 @@ public class AllAppsView extends RSSurfaceView { return true; } - DataSetObserver mIconObserver = new DataSetObserver() { - public void onChanged() { - Log.d(TAG, "new icons arrived! now have " + mAdapter.getCount()); - } - }; - public void setApps(ArrayList<ApplicationInfo> list) { mAllAppsList = list; if (mRollo != null) { mRollo.setApps(list); } mPageCount = countPages(list.size()); + Log.d(TAG, "setApps mRollo=" + mRollo + " list=" + list); + } + + private void invokeIcon(int index) { + Log.d(TAG, "launch it!!!! index=" + index); } private static int countPages(int iconCount) { @@ -276,15 +337,20 @@ public class AllAppsView extends RSSurfaceView { private Allocation mScrollHandle; private Allocation[] mIcons; - private int[] mAllocIconIDBuf; + private int[] mIconIds; private Allocation mAllocIconID; private Allocation[] mLabels; - private int[] mAllocLabelIDBuf; + private int[] mLabelIds; private Allocation mAllocLabelID; + private Allocation mSelectedIcon; - private int[] mAllocScratchBuf; - private Allocation mAllocScratch; + private int[] mTouchYBorders; + private Allocation mAllocTouchYBorders; + private int[] mTouchXBorders; + private Allocation mAllocTouchXBorders; + + private Bitmap mSelectionBitmap; Params mParams; State mState; @@ -314,7 +380,9 @@ public class AllAppsView extends RSSurfaceView { @AllocationIndex(5) public int currentScrollX; @AllocationIndex(6) public int flingDuration; @AllocationIndex(7) public int flingEndPos; - @AllocationIndex(8) public int scrollHandlePos; + @AllocationIndex(8) public int startScrollX; + @AllocationIndex(9) public int selectedIconIndex = -1; + @AllocationIndex(10) public int selectedIconTexture; } public RolloRS() { @@ -326,6 +394,7 @@ public class AllAppsView extends RSSurfaceView { mHeight = height; initGl(); initData(); + initTouchState(); initRs(); } @@ -353,7 +422,8 @@ public class AllAppsView extends RSSurfaceView { mPFImages.bindSampler(mSampler, 0); bf.setTexEnvMode(ProgramFragment.EnvMode.MODULATE, 0); - mPFText = bf.create(); + //mPFText = bf.create(); + mPFText = (new ProgramFragment.Builder(mRS, null, null)).create(); mPFText.setName("PFText"); mPFText.bindSampler(mSamplerText, 0); @@ -391,9 +461,15 @@ public class AllAppsView extends RSSurfaceView { mRS.contextBindProgramVertex(mPV); - mAllocScratchBuf = new int[32]; - mAllocScratch = Allocation.createSized(mRS, Element.USER_I32, mAllocScratchBuf.length); - mAllocScratch.data(mAllocScratchBuf); + mTouchXBorders = new int[Defines.COLUMNS_PER_PAGE+1]; + mAllocTouchXBorders = Allocation.createSized(mRS, Element.USER_I32, + mTouchXBorders.length); + mAllocTouchXBorders.data(mTouchXBorders); + + mTouchYBorders = new int[Defines.ROWS_PER_PAGE+1]; + mAllocTouchYBorders = Allocation.createSized(mRS, Element.USER_I32, + mTouchYBorders.length); + mAllocTouchYBorders.data(mTouchYBorders); Log.e("rs", "Done loading named"); } @@ -410,17 +486,33 @@ public class AllAppsView extends RSSurfaceView { mParams.bubbleBitmapHeight = bubble.getBitmapHeight(); mScrollHandle = Allocation.createFromBitmapResource(mRS, mRes, - R.drawable.all_apps_button_pow2, Element.RGBA_8888, true); + R.drawable.all_apps_button_pow2, Element.RGBA_8888, false); mScrollHandle.uploadToTexture(0); mParams.scrollHandleId = mScrollHandle.getID(); Log.d(TAG, "mParams.scrollHandleId=" + mParams.scrollHandleId); mParams.scrollHandleTextureWidth = 128; mParams.scrollHandleTextureHeight = 128; - mState.scrollHandlePos = 0; + mParams.save(); mState.save(); + mSelectionBitmap = Bitmap.createBitmap(Defines.ICON_WIDTH_PX, Defines.ICON_HEIGHT_PX, + Bitmap.Config.ARGB_8888); + Bitmap selectionBitmap = mSelectionBitmap; + Paint paint = new Paint(); + float radius = 12 * getContext().getResources().getDisplayMetrics().density; + //paint.setMaskFilter(new BlurMaskFilter(radius, BlurMaskFilter.Blur.OUTER)); + Canvas canvas = new Canvas(selectionBitmap); + canvas.drawColor(0xffff0000); + + mSelectedIcon = Allocation.createFromBitmap(mRS, selectionBitmap, + Element.RGBA_8888, false); + mSelectedIcon.uploadToTexture(0); + + mState.selectedIconTexture = mSelectedIcon.getID(); + + Log.d(TAG, "initData calling mRollo.setApps"); setApps(null); } @@ -435,8 +527,9 @@ public class AllAppsView extends RSSurfaceView { mScript.bindAllocation(mParams.getAllocation(), Defines.ALLOC_PARAMS); mScript.bindAllocation(mState.getAllocation(), Defines.ALLOC_STATE); mScript.bindAllocation(mAllocIconID, Defines.ALLOC_ICON_IDS); - mScript.bindAllocation(mAllocScratch, Defines.ALLOC_SCRATCH); mScript.bindAllocation(mAllocLabelID, Defines.ALLOC_LABEL_IDS); + mScript.bindAllocation(mAllocTouchXBorders, Defines.ALLOC_X_BORDERS); + mScript.bindAllocation(mAllocTouchYBorders, Defines.ALLOC_Y_BORDERS); mRS.contextBindRootScript(mScript); } @@ -444,11 +537,11 @@ public class AllAppsView extends RSSurfaceView { private void setApps(ArrayList<ApplicationInfo> list) { final int count = list != null ? list.size() : 0; mIcons = new Allocation[count]; - mAllocIconIDBuf = new int[count]; + mIconIds = new int[count]; mAllocIconID = Allocation.createSized(mRS, Element.USER_I32, count); mLabels = new Allocation[count]; - mAllocLabelIDBuf = new int[count]; + mLabelIds = new int[count]; mAllocLabelID = Allocation.createSized(mRS, Element.USER_I32, count); Element ie8888 = Element.RGBA_8888; @@ -459,19 +552,19 @@ public class AllAppsView extends RSSurfaceView { final ApplicationInfo item = list.get(i); mIcons[i] = Allocation.createFromBitmap(mRS, item.iconBitmap, - Element.RGBA_8888, true); + Element.RGBA_8888, false); mLabels[i] = Allocation.createFromBitmap(mRS, item.titleBitmap, - Element.RGBA_8888, true); + Element.RGBA_8888, false); mIcons[i].uploadToTexture(0); mLabels[i].uploadToTexture(0); - mAllocIconIDBuf[i] = mIcons[i].getID(); - mAllocLabelIDBuf[i] = mLabels[i].getID(); + mIconIds[i] = mIcons[i].getID(); + mLabelIds[i] = mLabels[i].getID(); } - mAllocIconID.data(mAllocIconIDBuf); - mAllocLabelID.data(mAllocLabelIDBuf); + mAllocIconID.data(mIconIds); + mAllocLabelID.data(mLabelIds); mState.iconCount = count; @@ -484,6 +577,84 @@ public class AllAppsView extends RSSurfaceView { mState.save(); } + + void initTouchState() { + int width = getWidth(); + int height = getHeight(); + + int iconsSize; + if (width < height) { + iconsSize = width; + } else { + iconsSize = height; + } + int cellHeight = iconsSize / Defines.ROWS_PER_PAGE; + int cellWidth = iconsSize / Defines.COLUMNS_PER_PAGE; + + int centerY = (height / 2) - (int)(cellHeight * 0.35f); + mTouchYBorders[0] = centerY - (int)(2.4f * cellHeight); + mTouchYBorders[1] = centerY - (int)(1.15f * cellHeight); + mTouchYBorders[2] = centerY; + mTouchYBorders[3] = centerY + (int)(1.15f * cellHeight);; + mTouchYBorders[4] = centerY + (int)(2.4f * cellHeight); + + mAllocTouchYBorders.data(mTouchYBorders); + + int centerX = (width / 2); + mTouchXBorders[0] = centerX - (2 * cellWidth); + mTouchXBorders[1] = centerX - (int)(0.83f * cellWidth);; + mTouchXBorders[2] = centerX; + mTouchXBorders[3] = centerX + (int)(0.83f * cellWidth);; + mTouchXBorders[4] = centerX + (2 * cellWidth); + + mAllocTouchXBorders.data(mTouchXBorders); + } + + int chooseTappedIcon(int x, int y, int scrollX, int currentPage) { + int col = -1; + int row = -1; + + for (int i=0; i<Defines.COLUMNS_PER_PAGE; i++) { + if (x >= mTouchXBorders[i] && x < mTouchXBorders[i+1]) { + col = i; + break; + } + } + for (int i=0; i<Defines.ROWS_PER_PAGE; i++) { + if (y >= mTouchYBorders[i] && y < mTouchYBorders[i+1]) { + row = i; + break; + } + } + + if (row < 0 || col < 0) { + return -1; + } + + return (currentPage * Defines.ROWS_PER_PAGE * Defines.COLUMNS_PER_PAGE) + + (row * Defines.ROWS_PER_PAGE) + col; + } + + /** + * You need to call save() on mState on your own after calling this. + */ + void selectIcon(int x, int y, int scrollX, int currentPage) { + int iconCount = mAllAppsList.size(); + int index = chooseTappedIcon(x, y, scrollX, currentPage); + if (index < 0 || index >= iconCount) { + mState.selectedIconIndex = -1; + return; + } else { + mState.selectedIconIndex = index; + } + } + + /** + * You need to call save() on mState on your own after calling this. + */ + void clearSelectedIcon() { + mState.selectedIconIndex = -1; + } } } diff --git a/src/com/android/launcher2/AppInfoCache.java b/src/com/android/launcher2/AppInfoCache.java index 34e843e83..9e87a471c 100644 --- a/src/com/android/launcher2/AppInfoCache.java +++ b/src/com/android/launcher2/AppInfoCache.java @@ -163,9 +163,8 @@ public class AppInfoCache { application.title = info.activityInfo.name; } - Drawable icon = Utilities.createIconThumbnail(info.activityInfo.loadIcon(packageManager), - context, true); - application.iconBitmap = ((FastBitmapDrawable)icon).getBitmap(); + application.iconBitmap = Utilities.createAllAppsBitmap( + info.activityInfo.loadIcon(packageManager), context); application.filtered = true; application.titleBitmap = bubble.createTextBitmap(application.title.toString()); diff --git a/src/com/android/launcher2/ApplicationsAdapter.java b/src/com/android/launcher2/ApplicationsAdapter.java index fc69703ca..489f54695 100644 --- a/src/com/android/launcher2/ApplicationsAdapter.java +++ b/src/com/android/launcher2/ApplicationsAdapter.java @@ -45,7 +45,7 @@ public class ApplicationsAdapter extends ArrayAdapter<ApplicationInfo> { } if (!info.filtered) { - info.icon = Utilities.createIconThumbnail(info.icon, getContext(), false); + info.icon = Utilities.createIconThumbnail(info.icon, getContext()); info.filtered = true; } diff --git a/src/com/android/launcher2/FolderIcon.java b/src/com/android/launcher2/FolderIcon.java index c135fa3a2..85fc3a754 100644 --- a/src/com/android/launcher2/FolderIcon.java +++ b/src/com/android/launcher2/FolderIcon.java @@ -48,7 +48,7 @@ public class FolderIcon extends BubbleTextView implements DropTarget { final Resources resources = launcher.getResources(); Drawable d = resources.getDrawable(R.drawable.ic_launcher_folder); - d = Utilities.createIconThumbnail(d, launcher, false); + d = Utilities.createIconThumbnail(d, launcher); icon.mCloseIcon = d; icon.mOpenIcon = resources.getDrawable(R.drawable.ic_launcher_folder_open); icon.setCompoundDrawablesWithIntrinsicBounds(null, d, null, null); diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java index e1b213e90..bf08b4ebf 100644 --- a/src/com/android/launcher2/Launcher.java +++ b/src/com/android/launcher2/Launcher.java @@ -518,6 +518,7 @@ public final class Launcher extends Activity dragLayer.setDragController(dragController); mAllAppsGrid = (AllAppsView)dragLayer.findViewById(R.id.all_apps_view); + mAllAppsGrid.setLauncher(this); mWorkspace = (Workspace) dragLayer.findViewById(R.id.workspace); final Workspace workspace = mWorkspace; @@ -575,7 +576,7 @@ public final class Launcher extends Activity TextView favorite = (TextView) mInflater.inflate(layoutResId, parent, false); if (!info.filtered) { - info.icon = Utilities.createIconThumbnail(info.icon, this, false); + info.icon = Utilities.createIconThumbnail(info.icon, this); info.filtered = true; } @@ -873,7 +874,6 @@ public final class Launcher extends Activity TextKeyListener.getInstance().release(); - mAllAppsGrid.setAdapter(null); mModel.stopLoader(); unbindDesktopItems(); diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java index 90722cf0a..b261a75b9 100644 --- a/src/com/android/launcher2/LauncherModel.java +++ b/src/com/android/launcher2/LauncherModel.java @@ -944,7 +944,7 @@ public class LauncherModel { final ApplicationInfo info = new ApplicationInfo(); final ActivityInfo activityInfo = resolveInfo.activityInfo; - info.icon = Utilities.createIconThumbnail(activityInfo.loadIcon(manager), context, false); + info.icon = Utilities.createIconThumbnail(activityInfo.loadIcon(manager), context); if (info.title == null || info.title.length() == 0) { info.title = activityInfo.loadLabel(manager); } @@ -973,8 +973,7 @@ public class LauncherModel { try { Resources resources = packageManager.getResourcesForApplication(packageName); final int id = resources.getIdentifier(resourceName, null, null); - info.icon = Utilities.createIconThumbnail(resources.getDrawable(id), context, - false); + info.icon = Utilities.createIconThumbnail(resources.getDrawable(id), context); } catch (Exception e) { info.icon = packageManager.getDefaultActivityIcon(); } diff --git a/src/com/android/launcher2/LiveFolderAdapter.java b/src/com/android/launcher2/LiveFolderAdapter.java index 05e7a6a82..b0e9eff1f 100644 --- a/src/com/android/launcher2/LiveFolderAdapter.java +++ b/src/com/android/launcher2/LiveFolderAdapter.java @@ -154,8 +154,7 @@ class LiveFolderAdapter extends CursorAdapter { cursor.getString(holder.iconPackageIndex)); final int id = resources.getIdentifier(resource, null, null); - icon = Utilities.createIconThumbnail(resources.getDrawable(id), mContext, - false); + icon = Utilities.createIconThumbnail(resources.getDrawable(id), mContext); mIcons.put(resource, icon); } catch (Exception e) { // Ignore diff --git a/src/com/android/launcher2/LiveFolderIcon.java b/src/com/android/launcher2/LiveFolderIcon.java index d281a64e8..55f100cce 100644 --- a/src/com/android/launcher2/LiveFolderIcon.java +++ b/src/com/android/launcher2/LiveFolderIcon.java @@ -42,7 +42,7 @@ public class LiveFolderIcon extends FolderIcon { Drawable d = folderInfo.icon; if (d == null) { d = Utilities.createIconThumbnail(resources.getDrawable(R.drawable.ic_launcher_folder), - launcher, false); + launcher); folderInfo.filtered = true; } icon.setCompoundDrawablesWithIntrinsicBounds(null, d, null, null); diff --git a/src/com/android/launcher2/Utilities.java b/src/com/android/launcher2/Utilities.java index ca12a4d29..073b17927 100644 --- a/src/com/android/launcher2/Utilities.java +++ b/src/com/android/launcher2/Utilities.java @@ -41,6 +41,8 @@ import android.content.Context; final class Utilities { private static int sIconWidth = -1; private static int sIconHeight = -1; + private static int sIconTextureWidth = -1; + private static int sIconTextureHeight = -1; private static final Paint sPaint = new Paint(); private static final Rect sBounds = new Rect(); @@ -80,19 +82,14 @@ final class Utilities { * * @param icon The icon to get a thumbnail of. * @param context The application's context. - * @param forceBitmap If this is true, the drawable will always be redrawn - * into a new bitmap if it isn't already a BitmapDrawable or a - * FastBitmapDrawable. * * @return A thumbnail for the specified icon or the icon itself if the * thumbnail could not be created. */ - static Drawable createIconThumbnail(Drawable icon, Context context, boolean forceBitmap) { + static Drawable createIconThumbnail(Drawable icon, Context context) { synchronized (sCanvas) { // we share the statics :-( if (sIconWidth == -1) { - final Resources resources = context.getResources(); - sIconWidth = (int)resources.getDimension(android.R.dimen.app_icon_size); - sIconHeight = sIconWidth; + initStatics(context); } int width = sIconWidth; @@ -155,26 +152,91 @@ final class Utilities { icon = new FastBitmapDrawable(thumb); } } - - if (forceBitmap) { - // no intrinsic size --> use default size - int w = sIconWidth; - int h = sIconHeight; - final Bitmap.Config c = Bitmap.Config.ARGB_8888; - final Bitmap thumb = Bitmap.createBitmap(roundToPow2(w), roundToPow2(h), c); - final Canvas canvas = sCanvas; - canvas.setBitmap(thumb); - sOldBounds.set(icon.getBounds()); - icon.setBounds(0, 0, w, h); - icon.draw(canvas); - icon.setBounds(sOldBounds); - icon = new FastBitmapDrawable(thumb); - } return icon; } } + static int sColors[] = { 0xffff0000, 0xff00ff00, 0xff0000ff }; + static int sColorIndex = 0; + + /** + * Returns a bitmap suitable for the all apps view. The bitmap will be a power + * of two sized ARGB_8888 bitmap that can be used as a gl texture. + */ + static Bitmap createAllAppsBitmap(Drawable icon, Context context) { + synchronized (sCanvas) { // we share the statics :-( + if (sIconWidth == -1) { + initStatics(context); + } + + int width = sIconWidth; + int height = sIconHeight; + + float scale = 1.0f; + if (icon instanceof PaintDrawable) { + PaintDrawable painter = (PaintDrawable) icon; + painter.setIntrinsicWidth(width); + painter.setIntrinsicHeight(height); + } else if (icon instanceof BitmapDrawable) { + // Ensure the bitmap has a density. + BitmapDrawable bitmapDrawable = (BitmapDrawable) icon; + Bitmap bitmap = bitmapDrawable.getBitmap(); + if (bitmap.getDensity() == Bitmap.DENSITY_NONE) { + bitmapDrawable.setTargetDensity(context.getResources().getDisplayMetrics()); + } + } + int sourceWidth = icon.getIntrinsicWidth(); + int sourceHeight = icon.getIntrinsicHeight(); + + if (sourceWidth > 0 && sourceWidth > 0) { + // There are intrinsic sizes. + if (width < sourceWidth || height < sourceHeight || scale != 1.0f) { + // It's too big, scale it down. + final float ratio = (float) sourceWidth / sourceHeight; + if (sourceWidth > sourceHeight) { + height = (int) (width / ratio); + } else if (sourceHeight > sourceWidth) { + width = (int) (height * ratio); + } + } else if (sourceWidth < width && sourceHeight < height) { + // It's small, use the size they gave us. + width = sourceWidth; + height = sourceWidth; + } + } + + // no intrinsic size --> use default size + int textureWidth = sIconTextureWidth; + int textureHeight = sIconTextureHeight; + + final Bitmap bitmap = Bitmap.createBitmap(textureWidth, textureHeight, + Bitmap.Config.ARGB_8888); + final Canvas canvas = sCanvas; + canvas.setBitmap(bitmap); + + final int left = (textureWidth-width) / 2; + final int top = (textureHeight-height) / 2; + + if (false) { + // draw a big box for the icon for debugging + canvas.drawColor(sColors[sColorIndex]); + if (++sColorIndex >= sColors.length) sColorIndex = 0; + Paint debugPaint = new Paint(); + debugPaint.setColor(0xffcccc00); + canvas.drawRect(left, top, left+width, top+height, debugPaint); + } + + sOldBounds.set(icon.getBounds()); + icon.setBounds(left, top, left+width, top+height); + icon.draw(canvas); + icon.setBounds(sOldBounds); + + return bitmap; + } + } + + /** * Returns a Bitmap representing the thumbnail of the specified Bitmap. * The size of the thumbnail is defined by the dimension @@ -189,9 +251,7 @@ final class Utilities { static Bitmap createBitmapThumbnail(Bitmap bitmap, Context context) { synchronized (sCanvas) { // we share the statics :-( if (sIconWidth == -1) { - final Resources resources = context.getResources(); - sIconWidth = sIconHeight = (int) resources.getDimension( - android.R.dimen.app_icon_size); + initStatics(context); } int width = sIconWidth; @@ -227,6 +287,12 @@ final class Utilities { } } + private static void initStatics(Context context) { + final Resources resources = context.getResources(); + sIconWidth = sIconHeight = (int) resources.getDimension(android.R.dimen.app_icon_size); + sIconTextureWidth = sIconTextureHeight = roundToPow2(sIconWidth); + } + static class BubbleText { private static final int MAX_LINES = 2; private TextPaint mTextPaint; diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java index 8b0048368..744cf720f 100644 --- a/src/com/android/launcher2/Workspace.java +++ b/src/com/android/launcher2/Workspace.java @@ -1288,7 +1288,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag final Drawable icon = AppInfoCache.getIconDrawable(pm, info); if (icon != null && icon != info.icon) { info.icon.setCallback(null); - info.icon = Utilities.createIconThumbnail(icon, mContext, false); + info.icon = Utilities.createIconThumbnail(icon, mContext); info.filtered = true; ((TextView) view).setCompoundDrawablesWithIntrinsicBounds(null, info.icon, null, null); |