1321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung/* 2321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * Copyright (C) 2010 The Android Open Source Project 3321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * 4321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * Licensed under the Apache License, Version 2.0 (the "License"); 5321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * you may not use this file except in compliance with the License. 6321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * You may obtain a copy of the License at 7321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * 8321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * http://www.apache.org/licenses/LICENSE-2.0 9321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * 10321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * Unless required by applicable law or agreed to in writing, software 11321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * distributed under the License is distributed on an "AS IS" BASIS, 12321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * See the License for the specific language governing permissions and 14321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * limitations under the License. 15321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung */ 16321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 17321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chungpackage com.android.launcher2; 18321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 19321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chungimport android.content.Context; 20785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.content.res.Resources; 21321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chungimport android.util.AttributeSet; 22321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chungimport android.view.MotionEvent; 23321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chungimport android.view.View; 24321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chungimport android.view.ViewDebug; 25321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chungimport android.view.ViewGroup; 26321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 27785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport com.android.launcher.R; 28785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung 29321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung/** 30321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * An abstraction of the original CellLayout which supports laying out items 31321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * which span multiple cells into a grid-like layout. Also supports dimming 32321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * to give a preview of its contents. 33321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung */ 348245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurkapublic class PagedViewCellLayout extends ViewGroup implements Page { 35321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung static final String TAG = "PagedViewCellLayout"; 36321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 37321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung private int mCellCountX; 38321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung private int mCellCountY; 39db1138b4efae89a3b5833547958a3606e5408a71Winson Chung private int mOriginalCellWidth; 40db1138b4efae89a3b5833547958a3606e5408a71Winson Chung private int mOriginalCellHeight; 41321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung private int mCellWidth; 42321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung private int mCellHeight; 43234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen private int mOriginalWidthGap; 44234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen private int mOriginalHeightGap; 45df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung private int mWidthGap; 46df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung private int mHeightGap; 47db1138b4efae89a3b5833547958a3606e5408a71Winson Chung private int mMaxGap; 488245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka protected PagedViewCellLayoutChildren mChildren; 49321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 50321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung public PagedViewCellLayout(Context context) { 51321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung this(context, null); 52321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 53321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 54321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung public PagedViewCellLayout(Context context, AttributeSet attrs) { 55321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung this(context, attrs, 0); 56321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 57321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 58321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung public PagedViewCellLayout(Context context, AttributeSet attrs, int defStyle) { 59321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung super(context, attrs, defStyle); 60321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 61321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung setAlwaysDrawnWithCacheEnabled(false); 62321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 63321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung // setup default cell parameters 64785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung Resources resources = context.getResources(); 65db1138b4efae89a3b5833547958a3606e5408a71Winson Chung mOriginalCellWidth = mCellWidth = 66db1138b4efae89a3b5833547958a3606e5408a71Winson Chung resources.getDimensionPixelSize(R.dimen.apps_customize_cell_width); 67db1138b4efae89a3b5833547958a3606e5408a71Winson Chung mOriginalCellHeight = mCellHeight = 68db1138b4efae89a3b5833547958a3606e5408a71Winson Chung resources.getDimensionPixelSize(R.dimen.apps_customize_cell_height); 69321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung mCellCountX = LauncherModel.getCellCountX(); 70321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung mCellCountY = LauncherModel.getCellCountY(); 716032e7ed8e6208348a6b3f8bc1a7ecafc7951af8Winson Chung mOriginalWidthGap = mOriginalHeightGap = mWidthGap = mHeightGap = -1; 72db1138b4efae89a3b5833547958a3606e5408a71Winson Chung mMaxGap = resources.getDimensionPixelSize(R.dimen.apps_customize_max_gap); 73321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 748245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka mChildren = new PagedViewCellLayoutChildren(context); 758245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka mChildren.setCellDimensions(mCellWidth, mCellHeight); 768245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka mChildren.setGap(mWidthGap, mHeightGap); 778245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka 788245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka addView(mChildren); 79321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 80321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 81244d74cb353f1260c4d633e719bf84bb3b6e52bcPatrick Dubroy public int getCellWidth() { 82244d74cb353f1260c4d633e719bf84bb3b6e52bcPatrick Dubroy return mCellWidth; 83244d74cb353f1260c4d633e719bf84bb3b6e52bcPatrick Dubroy } 84244d74cb353f1260c4d633e719bf84bb3b6e52bcPatrick Dubroy 85244d74cb353f1260c4d633e719bf84bb3b6e52bcPatrick Dubroy public int getCellHeight() { 86244d74cb353f1260c4d633e719bf84bb3b6e52bcPatrick Dubroy return mCellHeight; 87244d74cb353f1260c4d633e719bf84bb3b6e52bcPatrick Dubroy } 88244d74cb353f1260c4d633e719bf84bb3b6e52bcPatrick Dubroy 89321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung @Override 90b3347bb9f4ccf41fb7043bca66c3a565bde1083bWinson Chung public void setAlpha(float alpha) { 9122f823d340710bcde587b18a1542570cbe0360f5Adam Cohen mChildren.setAlpha(alpha); 92321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 93321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 94c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka void destroyHardwareLayers() { 95abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka // called when a page is no longer visible (triggered by loadAssociatedPages -> 96abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka // removeAllViewsOnPage) 9722f823d340710bcde587b18a1542570cbe0360f5Adam Cohen mChildren.destroyHardwareLayer(); 98c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka } 9922f823d340710bcde587b18a1542570cbe0360f5Adam Cohen 100c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka void createHardwareLayers() { 101abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka // called when a page is visible (triggered by loadAssociatedPages -> syncPageItems) 10222f823d340710bcde587b18a1542570cbe0360f5Adam Cohen mChildren.createHardwareLayer(); 103c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka } 104c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka 105321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung @Override 106321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung public void cancelLongPress() { 107321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung super.cancelLongPress(); 108321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 109321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung // Cancel long press for all children 110321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung final int count = getChildCount(); 111321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung for (int i = 0; i < count; i++) { 112321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung final View child = getChildAt(i); 113321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung child.cancelLongPress(); 114321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 115321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 116321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 117321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung public boolean addViewToCellLayout(View child, int index, int childId, 1186a70e9fc3c62cc83d6abe59323d622dc6cd224a7Winson Chung PagedViewCellLayout.LayoutParams params) { 119321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung final PagedViewCellLayout.LayoutParams lp = params; 120321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 121321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung // Generate an id for each view, this assumes we have at most 256x256 cells 122321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung // per workspace screen 123321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung if (lp.cellX >= 0 && lp.cellX <= (mCellCountX - 1) && 124321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung lp.cellY >= 0 && (lp.cellY <= mCellCountY - 1)) { 125321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung // If the horizontal or vertical span is set to -1, it is taken to 126321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung // mean that it spans the extent of the CellLayout 127321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung if (lp.cellHSpan < 0) lp.cellHSpan = mCellCountX; 128321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung if (lp.cellVSpan < 0) lp.cellVSpan = mCellCountY; 129321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 130321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung child.setId(childId); 1318245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka mChildren.addView(child, index, lp); 132321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 133321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung return true; 134321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 135321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung return false; 136321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 137321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 138321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung @Override 1398245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka public void removeAllViewsOnPage() { 1408245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka mChildren.removeAllViews(); 141c5e49022bea70a1b0b6ada5431afbb6e951cc3f6Michael Jurka destroyHardwareLayers(); 142321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 143321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 144321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung @Override 1458245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka public void removeViewOnPageAt(int index) { 1468245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka mChildren.removeViewAt(index); 1478245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka } 1488245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka 149c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung /** 150c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung * Clears all the key listeners for the individual icons. 151c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung */ 152c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung public void resetChildrenOnKeyListeners() { 153c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung int childCount = mChildren.getChildCount(); 154c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung for (int j = 0; j < childCount; ++j) { 155c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung mChildren.getChildAt(j).setOnKeyListener(null); 156c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung } 157c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung } 158c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung 1598245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka @Override 1608245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka public int getPageChildCount() { 1618245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka return mChildren.getChildCount(); 1628245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka } 1638245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka 1645afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung public PagedViewCellLayoutChildren getChildrenLayout() { 1655afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung return mChildren; 1665afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung } 1675afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung 1688245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka @Override 1698245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka public View getChildOnPageAt(int i) { 1708245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka return mChildren.getChildAt(i); 1718245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka } 1728245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka 1738245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka @Override 1748245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka public int indexOfChildOnPage(View v) { 1758245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka return mChildren.indexOfChild(v); 1768245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka } 1778245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka 17897d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung public int getCellCountX() { 17997d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung return mCellCountX; 18097d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung } 18197d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung 18297d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung public int getCellCountY() { 18397d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung return mCellCountY; 18497d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung } 18597d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung 186321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 187321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec); 188321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec); 189321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 190321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec); 191321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec); 192321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 193321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung if (widthSpecMode == MeasureSpec.UNSPECIFIED || heightSpecMode == MeasureSpec.UNSPECIFIED) { 194321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung throw new RuntimeException("CellLayout cannot have UNSPECIFIED dimensions"); 195321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 196321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 197321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung int numWidthGaps = mCellCountX - 1; 198321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung int numHeightGaps = mCellCountY - 1; 199321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 200234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen if (mOriginalWidthGap < 0 || mOriginalHeightGap < 0) { 201db1138b4efae89a3b5833547958a3606e5408a71Winson Chung int hSpace = widthSpecSize - mPaddingLeft - mPaddingRight; 202db1138b4efae89a3b5833547958a3606e5408a71Winson Chung int vSpace = heightSpecSize - mPaddingTop - mPaddingBottom; 203db1138b4efae89a3b5833547958a3606e5408a71Winson Chung int hFreeSpace = hSpace - (mCellCountX * mOriginalCellWidth); 204db1138b4efae89a3b5833547958a3606e5408a71Winson Chung int vFreeSpace = vSpace - (mCellCountY * mOriginalCellHeight); 205db1138b4efae89a3b5833547958a3606e5408a71Winson Chung mWidthGap = Math.min(mMaxGap, numWidthGaps > 0 ? (hFreeSpace / numWidthGaps) : 0); 206db1138b4efae89a3b5833547958a3606e5408a71Winson Chung mHeightGap = Math.min(mMaxGap,numHeightGaps > 0 ? (vFreeSpace / numHeightGaps) : 0); 207db1138b4efae89a3b5833547958a3606e5408a71Winson Chung 208db1138b4efae89a3b5833547958a3606e5408a71Winson Chung mChildren.setGap(mWidthGap, mHeightGap); 209234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen } else { 210234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen mWidthGap = mOriginalWidthGap; 211234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen mHeightGap = mOriginalHeightGap; 212df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung } 213321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 214db1138b4efae89a3b5833547958a3606e5408a71Winson Chung // Initial values correspond to widthSpecMode == MeasureSpec.EXACTLY 215db1138b4efae89a3b5833547958a3606e5408a71Winson Chung int newWidth = widthSpecSize; 216db1138b4efae89a3b5833547958a3606e5408a71Winson Chung int newHeight = heightSpecSize; 217db1138b4efae89a3b5833547958a3606e5408a71Winson Chung if (widthSpecMode == MeasureSpec.AT_MOST) { 218db1138b4efae89a3b5833547958a3606e5408a71Winson Chung newWidth = mPaddingLeft + mPaddingRight + (mCellCountX * mCellWidth) + 219db1138b4efae89a3b5833547958a3606e5408a71Winson Chung ((mCellCountX - 1) * mWidthGap); 220db1138b4efae89a3b5833547958a3606e5408a71Winson Chung newHeight = mPaddingTop + mPaddingBottom + (mCellCountY * mCellHeight) + 221db1138b4efae89a3b5833547958a3606e5408a71Winson Chung ((mCellCountY - 1) * mHeightGap); 222db1138b4efae89a3b5833547958a3606e5408a71Winson Chung setMeasuredDimension(newWidth, newHeight); 223db1138b4efae89a3b5833547958a3606e5408a71Winson Chung } 224321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 225321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung final int count = getChildCount(); 226321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung for (int i = 0; i < count; i++) { 227321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung View child = getChildAt(i); 2288245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka int childWidthMeasureSpec = 229db1138b4efae89a3b5833547958a3606e5408a71Winson Chung MeasureSpec.makeMeasureSpec(newWidth - mPaddingLeft - 230db1138b4efae89a3b5833547958a3606e5408a71Winson Chung mPaddingRight, MeasureSpec.EXACTLY); 2318245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka int childheightMeasureSpec = 232db1138b4efae89a3b5833547958a3606e5408a71Winson Chung MeasureSpec.makeMeasureSpec(newHeight - mPaddingTop - 233db1138b4efae89a3b5833547958a3606e5408a71Winson Chung mPaddingBottom, MeasureSpec.EXACTLY); 234321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung child.measure(childWidthMeasureSpec, childheightMeasureSpec); 235321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 236321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 237db1138b4efae89a3b5833547958a3606e5408a71Winson Chung setMeasuredDimension(newWidth, newHeight); 238321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 239321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 2407ef959b9177e1e715b0afe010904455a3d961fc4Michael Jurka int getContentWidth() { 241f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung return getWidthBeforeFirstLayout() + mPaddingLeft + mPaddingRight; 2420413dfa01b822e349092636774dc948b9230adeaMichael Jurka } 2430413dfa01b822e349092636774dc948b9230adeaMichael Jurka 2444b576be59e58072cc03b5a8d36afb6a322513575Winson Chung int getContentHeight() { 2454a5ad095303ca1b6b745263269333bd087168d3cPatrick Dubroy if (mCellCountY > 0) { 2464a5ad095303ca1b6b745263269333bd087168d3cPatrick Dubroy return mCellCountY * mCellHeight + (mCellCountY - 1) * Math.max(0, mHeightGap); 2474a5ad095303ca1b6b745263269333bd087168d3cPatrick Dubroy } 2484a5ad095303ca1b6b745263269333bd087168d3cPatrick Dubroy return 0; 2494b576be59e58072cc03b5a8d36afb6a322513575Winson Chung } 2504b576be59e58072cc03b5a8d36afb6a322513575Winson Chung 251d92e741ca67c58c4be01a64940847feafe26a4b1Michael Jurka int getWidthBeforeFirstLayout() { 2524a5ad095303ca1b6b745263269333bd087168d3cPatrick Dubroy if (mCellCountX > 0) { 2534a5ad095303ca1b6b745263269333bd087168d3cPatrick Dubroy return mCellCountX * mCellWidth + (mCellCountX - 1) * Math.max(0, mWidthGap); 2544a5ad095303ca1b6b745263269333bd087168d3cPatrick Dubroy } 2554a5ad095303ca1b6b745263269333bd087168d3cPatrick Dubroy return 0; 2567ef959b9177e1e715b0afe010904455a3d961fc4Michael Jurka } 2577ef959b9177e1e715b0afe010904455a3d961fc4Michael Jurka 258321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung @Override 259321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung protected void onLayout(boolean changed, int l, int t, int r, int b) { 260321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung int count = getChildCount(); 261321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung for (int i = 0; i < count; i++) { 262321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung View child = getChildAt(i); 2639bfe2b2646f3849f5463c63876c184e820a7f03bMichael Jurka child.layout(mPaddingLeft, mPaddingTop, 2649bfe2b2646f3849f5463c63876c184e820a7f03bMichael Jurka r - l - mPaddingRight, b - t - mPaddingBottom); 265321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 266321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 267321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 268321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung @Override 269321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung public boolean onTouchEvent(MotionEvent event) { 270f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung boolean result = super.onTouchEvent(event); 271f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung int count = getPageChildCount(); 272f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung if (count > 0) { 273f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung // We only intercept the touch if we are tapping in empty space after the final row 274f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung View child = getChildOnPageAt(count - 1); 275f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung int bottom = child.getBottom(); 276f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung int numRows = (int) Math.ceil((float) getPageChildCount() / getCellCountX()); 277f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung if (numRows < getCellCountY()) { 278f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung // Add a little bit of buffer if there is room for another row 279f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung bottom += mCellHeight / 2; 280f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung } 281f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung result = result || (event.getY() < bottom); 282f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung } 283f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung return result; 284321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 285321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 28680baf5a6b3c62a62265f626d43d1167783c94131Winson Chung public void enableCenteredContent(boolean enabled) { 2878245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka mChildren.enableCenteredContent(enabled); 28880baf5a6b3c62a62265f626d43d1167783c94131Winson Chung } 28980baf5a6b3c62a62265f626d43d1167783c94131Winson Chung 290321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung @Override 291321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung protected void setChildrenDrawingCacheEnabled(boolean enabled) { 2928245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka mChildren.setChildrenDrawingCacheEnabled(enabled); 293321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 294321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 295321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung public void setCellCount(int xCount, int yCount) { 296321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung mCellCountX = xCount; 297321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung mCellCountY = yCount; 298321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung requestLayout(); 299321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 300321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 301df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung public void setGap(int widthGap, int heightGap) { 3026032e7ed8e6208348a6b3f8bc1a7ecafc7951af8Winson Chung mOriginalWidthGap = mWidthGap = widthGap; 3036032e7ed8e6208348a6b3f8bc1a7ecafc7951af8Winson Chung mOriginalHeightGap = mHeightGap = heightGap; 3048245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka mChildren.setGap(widthGap, heightGap); 305df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung } 306df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung 30780baf5a6b3c62a62265f626d43d1167783c94131Winson Chung public int[] getCellCountForDimensions(int width, int height) { 30880baf5a6b3c62a62265f626d43d1167783c94131Winson Chung // Always assume we're working with the smallest span to make sure we 30980baf5a6b3c62a62265f626d43d1167783c94131Winson Chung // reserve enough space in both orientations 31080baf5a6b3c62a62265f626d43d1167783c94131Winson Chung int smallerSize = Math.min(mCellWidth, mCellHeight); 31180baf5a6b3c62a62265f626d43d1167783c94131Winson Chung 31280baf5a6b3c62a62265f626d43d1167783c94131Winson Chung // Always round up to next largest cell 31380baf5a6b3c62a62265f626d43d1167783c94131Winson Chung int spanX = (width + smallerSize) / smallerSize; 31480baf5a6b3c62a62265f626d43d1167783c94131Winson Chung int spanY = (height + smallerSize) / smallerSize; 31580baf5a6b3c62a62265f626d43d1167783c94131Winson Chung 31680baf5a6b3c62a62265f626d43d1167783c94131Winson Chung return new int[] { spanX, spanY }; 31780baf5a6b3c62a62265f626d43d1167783c94131Winson Chung } 31880baf5a6b3c62a62265f626d43d1167783c94131Winson Chung 319321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung /** 320321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * Start dragging the specified child 321321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * 322321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * @param child The child that is being dragged 323321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung */ 324321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung void onDragChild(View child) { 325321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung PagedViewCellLayout.LayoutParams lp = (PagedViewCellLayout.LayoutParams) child.getLayoutParams(); 326321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung lp.isDragging = true; 327321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 328321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 329e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung /** 330e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung * Estimates the number of cells that the specified width would take up. 331e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung */ 33280baf5a6b3c62a62265f626d43d1167783c94131Winson Chung public int estimateCellHSpan(int width) { 3336032e7ed8e6208348a6b3f8bc1a7ecafc7951af8Winson Chung // We don't show the next/previous pages any more, so we use the full width, minus the 3346032e7ed8e6208348a6b3f8bc1a7ecafc7951af8Winson Chung // padding 3356032e7ed8e6208348a6b3f8bc1a7ecafc7951af8Winson Chung int availWidth = width - (mPaddingLeft + mPaddingRight); 336f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung 337f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung // We know that we have to fit N cells with N-1 width gaps, so we just juggle to solve for N 338f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung int n = Math.max(1, (availWidth + mWidthGap) / (mCellWidth + mWidthGap)); 339f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung 340f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung // We don't do anything fancy to determine if we squeeze another row in. 341f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung return n; 34280baf5a6b3c62a62265f626d43d1167783c94131Winson Chung } 343e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung 344e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung /** 345e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung * Estimates the number of cells that the specified height would take up. 346e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung */ 34780baf5a6b3c62a62265f626d43d1167783c94131Winson Chung public int estimateCellVSpan(int height) { 348f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung // The space for a page is the height - top padding (current page) - bottom padding (current 349f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung // page) 350f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung int availHeight = height - (mPaddingTop + mPaddingBottom); 351f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung 352f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung // We know that we have to fit N cells with N-1 height gaps, so we juggle to solve for N 353f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung int n = Math.max(1, (availHeight + mHeightGap) / (mCellHeight + mHeightGap)); 354f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung 355f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung // We don't do anything fancy to determine if we squeeze another row in. 356f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung return n; 357f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung } 358f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung 3597d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung /** Returns an estimated center position of the cell at the specified index */ 3607d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung public int[] estimateCellPosition(int x, int y) { 3617d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung return new int[] { 3627d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung mPaddingLeft + (x * mCellWidth) + (x * mWidthGap) + (mCellWidth / 2), 3637d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung mPaddingTop + (y * mCellHeight) + (y * mHeightGap) + (mCellHeight / 2) 3647d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung }; 3657d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung } 3667d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung 367f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung public void calculateCellCount(int width, int height, int maxCellCountX, int maxCellCountY) { 368f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung mCellCountX = Math.min(maxCellCountX, estimateCellHSpan(width)); 369f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung mCellCountY = Math.min(maxCellCountY, estimateCellVSpan(height)); 370f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung requestLayout(); 37180baf5a6b3c62a62265f626d43d1167783c94131Winson Chung } 372e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung 373e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung /** 3745fc72b31863639e70b3d944a3b650f42e46932a6Winson Chung * Estimates the width that the number of hSpan cells will take up. 375e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung */ 376e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung public int estimateCellWidth(int hSpan) { 377e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung // TODO: we need to take widthGap into effect 378e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung return hSpan * mCellWidth; 379e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung } 380e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung 381e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung /** 382e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung * Estimates the height that the number of vSpan cells will take up. 383e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung */ 384e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung public int estimateCellHeight(int vSpan) { 385e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung // TODO: we need to take heightGap into effect 386e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung return vSpan * mCellHeight; 38780baf5a6b3c62a62265f626d43d1167783c94131Winson Chung } 38880baf5a6b3c62a62265f626d43d1167783c94131Winson Chung 389321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung @Override 390321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { 391321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung return new PagedViewCellLayout.LayoutParams(getContext(), attrs); 392321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 393321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 394321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung @Override 395321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { 396321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung return p instanceof PagedViewCellLayout.LayoutParams; 397321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 398321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 399321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung @Override 400321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { 401321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung return new PagedViewCellLayout.LayoutParams(p); 402321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 403321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 404321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung public static class LayoutParams extends ViewGroup.MarginLayoutParams { 405321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung /** 406321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * Horizontal location of the item in the grid. 407321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung */ 408321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung @ViewDebug.ExportedProperty 409321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung public int cellX; 410321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 411321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung /** 412321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * Vertical location of the item in the grid. 413321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung */ 414321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung @ViewDebug.ExportedProperty 415321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung public int cellY; 416321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 417321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung /** 418321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * Number of cells spanned horizontally by the item. 419321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung */ 420321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung @ViewDebug.ExportedProperty 421321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung public int cellHSpan; 422321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 423321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung /** 424321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * Number of cells spanned vertically by the item. 425321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung */ 426321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung @ViewDebug.ExportedProperty 427321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung public int cellVSpan; 428321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 429321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung /** 430321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * Is this item currently being dragged 431321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung */ 432321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung public boolean isDragging; 433321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 43480baf5a6b3c62a62265f626d43d1167783c94131Winson Chung // a data object that you can bind to this layout params 43580baf5a6b3c62a62265f626d43d1167783c94131Winson Chung private Object mTag; 43680baf5a6b3c62a62265f626d43d1167783c94131Winson Chung 437321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung // X coordinate of the view in the layout. 438321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung @ViewDebug.ExportedProperty 439321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung int x; 440321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung // Y coordinate of the view in the layout. 441321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung @ViewDebug.ExportedProperty 442321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung int y; 443321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 44480baf5a6b3c62a62265f626d43d1167783c94131Winson Chung public LayoutParams() { 44580baf5a6b3c62a62265f626d43d1167783c94131Winson Chung super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 44680baf5a6b3c62a62265f626d43d1167783c94131Winson Chung cellHSpan = 1; 44780baf5a6b3c62a62265f626d43d1167783c94131Winson Chung cellVSpan = 1; 44880baf5a6b3c62a62265f626d43d1167783c94131Winson Chung } 44980baf5a6b3c62a62265f626d43d1167783c94131Winson Chung 450321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung public LayoutParams(Context c, AttributeSet attrs) { 451321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung super(c, attrs); 452321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung cellHSpan = 1; 453321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung cellVSpan = 1; 454321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 455321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 456321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung public LayoutParams(ViewGroup.LayoutParams source) { 457321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung super(source); 458321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung cellHSpan = 1; 459321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung cellVSpan = 1; 460321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 461321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 462321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung public LayoutParams(LayoutParams source) { 463321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung super(source); 464321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung this.cellX = source.cellX; 465321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung this.cellY = source.cellY; 466321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung this.cellHSpan = source.cellHSpan; 467321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung this.cellVSpan = source.cellVSpan; 468321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 469321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 470321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung public LayoutParams(int cellX, int cellY, int cellHSpan, int cellVSpan) { 471321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 472321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung this.cellX = cellX; 473321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung this.cellY = cellY; 474321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung this.cellHSpan = cellHSpan; 475321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung this.cellVSpan = cellVSpan; 476321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 477321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 478321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung public void setup(int cellWidth, int cellHeight, int widthGap, int heightGap, 479321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung int hStartPadding, int vStartPadding) { 480321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 481321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung final int myCellHSpan = cellHSpan; 482321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung final int myCellVSpan = cellVSpan; 483321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung final int myCellX = cellX; 484321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung final int myCellY = cellY; 485321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 486321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung width = myCellHSpan * cellWidth + ((myCellHSpan - 1) * widthGap) - 487321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung leftMargin - rightMargin; 488321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung height = myCellVSpan * cellHeight + ((myCellVSpan - 1) * heightGap) - 489321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung topMargin - bottomMargin; 490321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 491a2eb17095dcffa75c1e9681fdc318fe6e0564321Michael Jurka if (LauncherApplication.isScreenLarge()) { 492785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung x = hStartPadding + myCellX * (cellWidth + widthGap) + leftMargin; 493785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung y = vStartPadding + myCellY * (cellHeight + heightGap) + topMargin; 494785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } else { 495785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung x = myCellX * (cellWidth + widthGap) + leftMargin; 496785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung y = myCellY * (cellHeight + heightGap) + topMargin; 497785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 498321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 499321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung 50080baf5a6b3c62a62265f626d43d1167783c94131Winson Chung public Object getTag() { 50180baf5a6b3c62a62265f626d43d1167783c94131Winson Chung return mTag; 50280baf5a6b3c62a62265f626d43d1167783c94131Winson Chung } 50380baf5a6b3c62a62265f626d43d1167783c94131Winson Chung 50480baf5a6b3c62a62265f626d43d1167783c94131Winson Chung public void setTag(Object tag) { 50580baf5a6b3c62a62265f626d43d1167783c94131Winson Chung mTag = tag; 50680baf5a6b3c62a62265f626d43d1167783c94131Winson Chung } 50780baf5a6b3c62a62265f626d43d1167783c94131Winson Chung 508321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung public String toString() { 50980baf5a6b3c62a62265f626d43d1167783c94131Winson Chung return "(" + this.cellX + ", " + this.cellY + ", " + 51080baf5a6b3c62a62265f626d43d1167783c94131Winson Chung this.cellHSpan + ", " + this.cellVSpan + ")"; 511321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 512321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung } 513321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung} 5148245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka 5158245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurkainterface Page { 5168245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka public int getPageChildCount(); 5178245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka public View getChildOnPageAt(int i); 5188245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka public void removeAllViewsOnPage(); 5198245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka public void removeViewOnPageAt(int i); 5208245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka public int indexOfChildOnPage(View v); 5218245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka} 522