PagedViewCellLayout.java revision 7d7541e7b48fdc114c24b3b0aa75e70d7228041e
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;
22db1138b4efae89a3b5833547958a3606e5408a71Winson Chungimport android.util.Log;
23321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chungimport android.view.MotionEvent;
24321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chungimport android.view.View;
25321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chungimport android.view.ViewDebug;
26321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chungimport android.view.ViewGroup;
27321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
28785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport com.android.launcher.R;
29785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
30321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung/**
31321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * An abstraction of the original CellLayout which supports laying out items
32321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * which span multiple cells into a grid-like layout.  Also supports dimming
33321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * to give a preview of its contents.
34321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung */
358245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurkapublic class PagedViewCellLayout extends ViewGroup implements Page {
36321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    static final String TAG = "PagedViewCellLayout";
37321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
38321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    private int mCellCountX;
39321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    private int mCellCountY;
40db1138b4efae89a3b5833547958a3606e5408a71Winson Chung    private int mOriginalCellWidth;
41db1138b4efae89a3b5833547958a3606e5408a71Winson Chung    private int mOriginalCellHeight;
42321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    private int mCellWidth;
43321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    private int mCellHeight;
44234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen    private int mOriginalWidthGap;
45234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen    private int mOriginalHeightGap;
46df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung    private int mWidthGap;
47df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung    private int mHeightGap;
48db1138b4efae89a3b5833547958a3606e5408a71Winson Chung    private int mMaxGap;
498245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    protected PagedViewCellLayoutChildren mChildren;
50321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
51321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    public PagedViewCellLayout(Context context) {
52321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        this(context, null);
53321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
54321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
55321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    public PagedViewCellLayout(Context context, AttributeSet attrs) {
56321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        this(context, attrs, 0);
57321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
58321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
59321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    public PagedViewCellLayout(Context context, AttributeSet attrs, int defStyle) {
60321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        super(context, attrs, defStyle);
61321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
62321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        setAlwaysDrawnWithCacheEnabled(false);
63321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
64321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        // setup default cell parameters
65785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        Resources resources = context.getResources();
66db1138b4efae89a3b5833547958a3606e5408a71Winson Chung        mOriginalCellWidth = mCellWidth =
67db1138b4efae89a3b5833547958a3606e5408a71Winson Chung            resources.getDimensionPixelSize(R.dimen.apps_customize_cell_width);
68db1138b4efae89a3b5833547958a3606e5408a71Winson Chung        mOriginalCellHeight = mCellHeight =
69db1138b4efae89a3b5833547958a3606e5408a71Winson Chung            resources.getDimensionPixelSize(R.dimen.apps_customize_cell_height);
70321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        mCellCountX = LauncherModel.getCellCountX();
71321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        mCellCountY = LauncherModel.getCellCountY();
72234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen        mOriginalHeightGap = mOriginalHeightGap = mWidthGap = mHeightGap = -1;
73db1138b4efae89a3b5833547958a3606e5408a71Winson Chung        mMaxGap = resources.getDimensionPixelSize(R.dimen.apps_customize_max_gap);
74321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
758245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mChildren = new PagedViewCellLayoutChildren(context);
768245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mChildren.setCellDimensions(mCellWidth, mCellHeight);
778245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mChildren.setGap(mWidthGap, mHeightGap);
788245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka
798245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        addView(mChildren);
80321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
81321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
82244d74cb353f1260c4d633e719bf84bb3b6e52bcPatrick Dubroy    public int getCellWidth() {
83244d74cb353f1260c4d633e719bf84bb3b6e52bcPatrick Dubroy        return mCellWidth;
84244d74cb353f1260c4d633e719bf84bb3b6e52bcPatrick Dubroy    }
85244d74cb353f1260c4d633e719bf84bb3b6e52bcPatrick Dubroy
86244d74cb353f1260c4d633e719bf84bb3b6e52bcPatrick Dubroy    public int getCellHeight() {
87244d74cb353f1260c4d633e719bf84bb3b6e52bcPatrick Dubroy        return mCellHeight;
88244d74cb353f1260c4d633e719bf84bb3b6e52bcPatrick Dubroy    }
89244d74cb353f1260c4d633e719bf84bb3b6e52bcPatrick Dubroy
90321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
91b3347bb9f4ccf41fb7043bca66c3a565bde1083bWinson Chung    public void setAlpha(float alpha) {
9222f823d340710bcde587b18a1542570cbe0360f5Adam Cohen        mChildren.setAlpha(alpha);
93321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
94321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
95c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka    void destroyHardwareLayers() {
96abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka        // called when a page is no longer visible (triggered by loadAssociatedPages ->
97abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka        // removeAllViewsOnPage)
9822f823d340710bcde587b18a1542570cbe0360f5Adam Cohen        mChildren.destroyHardwareLayer();
99c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka    }
10022f823d340710bcde587b18a1542570cbe0360f5Adam Cohen
101c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka    void createHardwareLayers() {
102abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka        // called when a page is visible (triggered by loadAssociatedPages -> syncPageItems)
10322f823d340710bcde587b18a1542570cbe0360f5Adam Cohen        mChildren.createHardwareLayer();
104c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka    }
105c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka
106321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
107321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    public void cancelLongPress() {
108321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        super.cancelLongPress();
109321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
110321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        // Cancel long press for all children
111321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        final int count = getChildCount();
112321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        for (int i = 0; i < count; i++) {
113321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            final View child = getChildAt(i);
114321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            child.cancelLongPress();
115321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
116321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
117321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
118321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    public boolean addViewToCellLayout(View child, int index, int childId,
1196a70e9fc3c62cc83d6abe59323d622dc6cd224a7Winson Chung            PagedViewCellLayout.LayoutParams params) {
120321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        final PagedViewCellLayout.LayoutParams lp = params;
121321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
122321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        // Generate an id for each view, this assumes we have at most 256x256 cells
123321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        // per workspace screen
124321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        if (lp.cellX >= 0 && lp.cellX <= (mCellCountX - 1) &&
125321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung                lp.cellY >= 0 && (lp.cellY <= mCellCountY - 1)) {
126321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            // If the horizontal or vertical span is set to -1, it is taken to
127321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            // mean that it spans the extent of the CellLayout
128321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            if (lp.cellHSpan < 0) lp.cellHSpan = mCellCountX;
129321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            if (lp.cellVSpan < 0) lp.cellVSpan = mCellCountY;
130321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
131321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            child.setId(childId);
1328245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka            mChildren.addView(child, index, lp);
133321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
1348245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka            if (child instanceof PagedViewIcon) {
1358245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka                PagedViewIcon pagedViewIcon = (PagedViewIcon) child;
13622f823d340710bcde587b18a1542570cbe0360f5Adam Cohen                pagedViewIcon.disableCache();
1378245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka            }
138321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            return true;
139321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
140321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        return false;
141321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
142321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
143321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
1448245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public void removeAllViewsOnPage() {
1458245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mChildren.removeAllViews();
146c5e49022bea70a1b0b6ada5431afbb6e951cc3f6Michael Jurka        destroyHardwareLayers();
147321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
148321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
149321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
1508245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public void removeViewOnPageAt(int index) {
1518245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mChildren.removeViewAt(index);
1528245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    }
1538245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka
1548245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    @Override
1558245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public int getPageChildCount() {
1568245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        return mChildren.getChildCount();
1578245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    }
1588245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka
1595afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung    public PagedViewCellLayoutChildren getChildrenLayout() {
1605afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung        return mChildren;
1615afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung    }
1625afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung
1638245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    @Override
1648245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public View getChildOnPageAt(int i) {
1658245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        return mChildren.getChildAt(i);
1668245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    }
1678245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka
1688245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    @Override
1698245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public int indexOfChildOnPage(View v) {
1708245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        return mChildren.indexOfChild(v);
1718245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    }
1728245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka
17397d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung    public int getCellCountX() {
17497d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung        return mCellCountX;
17597d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung    }
17697d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung
17797d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung    public int getCellCountY() {
17897d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung        return mCellCountY;
17997d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung    }
18097d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung
181321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
182321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
183321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
184321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
185321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
186321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int heightSpecSize =  MeasureSpec.getSize(heightMeasureSpec);
187321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
188321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        if (widthSpecMode == MeasureSpec.UNSPECIFIED || heightSpecMode == MeasureSpec.UNSPECIFIED) {
189321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            throw new RuntimeException("CellLayout cannot have UNSPECIFIED dimensions");
190321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
191321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
192321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int numWidthGaps = mCellCountX - 1;
193321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int numHeightGaps = mCellCountY - 1;
194321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
195234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen        if (mOriginalWidthGap < 0 || mOriginalHeightGap < 0) {
196db1138b4efae89a3b5833547958a3606e5408a71Winson Chung            int hSpace = widthSpecSize - mPaddingLeft - mPaddingRight;
197db1138b4efae89a3b5833547958a3606e5408a71Winson Chung            int vSpace = heightSpecSize - mPaddingTop - mPaddingBottom;
198db1138b4efae89a3b5833547958a3606e5408a71Winson Chung            int hFreeSpace = hSpace - (mCellCountX * mOriginalCellWidth);
199db1138b4efae89a3b5833547958a3606e5408a71Winson Chung            int vFreeSpace = vSpace - (mCellCountY * mOriginalCellHeight);
200db1138b4efae89a3b5833547958a3606e5408a71Winson Chung            mWidthGap = Math.min(mMaxGap, numWidthGaps > 0 ? (hFreeSpace / numWidthGaps) : 0);
201db1138b4efae89a3b5833547958a3606e5408a71Winson Chung            mHeightGap = Math.min(mMaxGap,numHeightGaps > 0 ? (vFreeSpace / numHeightGaps) : 0);
202db1138b4efae89a3b5833547958a3606e5408a71Winson Chung
203db1138b4efae89a3b5833547958a3606e5408a71Winson Chung            mChildren.setGap(mWidthGap, mHeightGap);
204234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen        } else {
205234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen            mWidthGap = mOriginalWidthGap;
206234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen            mHeightGap = mOriginalHeightGap;
207df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung        }
208321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
209db1138b4efae89a3b5833547958a3606e5408a71Winson Chung        // Initial values correspond to widthSpecMode == MeasureSpec.EXACTLY
210db1138b4efae89a3b5833547958a3606e5408a71Winson Chung        int newWidth = widthSpecSize;
211db1138b4efae89a3b5833547958a3606e5408a71Winson Chung        int newHeight = heightSpecSize;
212db1138b4efae89a3b5833547958a3606e5408a71Winson Chung        if (widthSpecMode == MeasureSpec.AT_MOST) {
213db1138b4efae89a3b5833547958a3606e5408a71Winson Chung            newWidth = mPaddingLeft + mPaddingRight + (mCellCountX * mCellWidth) +
214db1138b4efae89a3b5833547958a3606e5408a71Winson Chung                ((mCellCountX - 1) * mWidthGap);
215db1138b4efae89a3b5833547958a3606e5408a71Winson Chung            newHeight = mPaddingTop + mPaddingBottom + (mCellCountY * mCellHeight) +
216db1138b4efae89a3b5833547958a3606e5408a71Winson Chung                ((mCellCountY - 1) * mHeightGap);
217db1138b4efae89a3b5833547958a3606e5408a71Winson Chung            setMeasuredDimension(newWidth, newHeight);
218db1138b4efae89a3b5833547958a3606e5408a71Winson Chung        }
219321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
220321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        final int count = getChildCount();
221321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        for (int i = 0; i < count; i++) {
222321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            View child = getChildAt(i);
2238245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka            int childWidthMeasureSpec =
224db1138b4efae89a3b5833547958a3606e5408a71Winson Chung                MeasureSpec.makeMeasureSpec(newWidth - mPaddingLeft -
225db1138b4efae89a3b5833547958a3606e5408a71Winson Chung                        mPaddingRight, MeasureSpec.EXACTLY);
2268245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka            int childheightMeasureSpec =
227db1138b4efae89a3b5833547958a3606e5408a71Winson Chung                MeasureSpec.makeMeasureSpec(newHeight - mPaddingTop -
228db1138b4efae89a3b5833547958a3606e5408a71Winson Chung                        mPaddingBottom, MeasureSpec.EXACTLY);
229321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            child.measure(childWidthMeasureSpec, childheightMeasureSpec);
230321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
231321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
232db1138b4efae89a3b5833547958a3606e5408a71Winson Chung        setMeasuredDimension(newWidth, newHeight);
233321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
234321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
2357ef959b9177e1e715b0afe010904455a3d961fc4Michael Jurka    int getContentWidth() {
236f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        return getWidthBeforeFirstLayout() + mPaddingLeft + mPaddingRight;
2370413dfa01b822e349092636774dc948b9230adeaMichael Jurka    }
2380413dfa01b822e349092636774dc948b9230adeaMichael Jurka
2394b576be59e58072cc03b5a8d36afb6a322513575Winson Chung    int getContentHeight() {
2404a5ad095303ca1b6b745263269333bd087168d3cPatrick Dubroy        if (mCellCountY > 0) {
2414a5ad095303ca1b6b745263269333bd087168d3cPatrick Dubroy            return mCellCountY * mCellHeight + (mCellCountY - 1) * Math.max(0, mHeightGap);
2424a5ad095303ca1b6b745263269333bd087168d3cPatrick Dubroy        }
2434a5ad095303ca1b6b745263269333bd087168d3cPatrick Dubroy        return 0;
2444b576be59e58072cc03b5a8d36afb6a322513575Winson Chung    }
2454b576be59e58072cc03b5a8d36afb6a322513575Winson Chung
246d92e741ca67c58c4be01a64940847feafe26a4b1Michael Jurka    int getWidthBeforeFirstLayout() {
2474a5ad095303ca1b6b745263269333bd087168d3cPatrick Dubroy        if (mCellCountX > 0) {
2484a5ad095303ca1b6b745263269333bd087168d3cPatrick Dubroy            return mCellCountX * mCellWidth + (mCellCountX - 1) * Math.max(0, mWidthGap);
2494a5ad095303ca1b6b745263269333bd087168d3cPatrick Dubroy        }
2504a5ad095303ca1b6b745263269333bd087168d3cPatrick Dubroy        return 0;
2517ef959b9177e1e715b0afe010904455a3d961fc4Michael Jurka    }
2527ef959b9177e1e715b0afe010904455a3d961fc4Michael Jurka
253321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
254321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    protected void onLayout(boolean changed, int l, int t, int r, int b) {
255321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int count = getChildCount();
256321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        for (int i = 0; i < count; i++) {
257321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            View child = getChildAt(i);
2589bfe2b2646f3849f5463c63876c184e820a7f03bMichael Jurka            child.layout(mPaddingLeft, mPaddingTop,
2599bfe2b2646f3849f5463c63876c184e820a7f03bMichael Jurka                r - l - mPaddingRight, b - t - mPaddingBottom);
260321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
261321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
262321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
263321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
264321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    public boolean onTouchEvent(MotionEvent event) {
265f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        boolean result = super.onTouchEvent(event);
266f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        int count = getPageChildCount();
267f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        if (count > 0) {
268f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung            // We only intercept the touch if we are tapping in empty space after the final row
269f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung            View child = getChildOnPageAt(count - 1);
270f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung            int bottom = child.getBottom();
271f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung            int numRows = (int) Math.ceil((float) getPageChildCount() / getCellCountX());
272f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung            if (numRows < getCellCountY()) {
273f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung                // Add a little bit of buffer if there is room for another row
274f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung                bottom += mCellHeight / 2;
275f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung            }
276f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung            result = result || (event.getY() < bottom);
277f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        }
278f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        return result;
279321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
280321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
28180baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    public void enableCenteredContent(boolean enabled) {
2828245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mChildren.enableCenteredContent(enabled);
28380baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    }
28480baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
285321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
286321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    protected void setChildrenDrawingCacheEnabled(boolean enabled) {
2878245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mChildren.setChildrenDrawingCacheEnabled(enabled);
288321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
289321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
290321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    public void setCellCount(int xCount, int yCount) {
291321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        mCellCountX = xCount;
292321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        mCellCountY = yCount;
293321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        requestLayout();
294321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
295321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
296df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung    public void setGap(int widthGap, int heightGap) {
297df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung        mWidthGap = widthGap;
298df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung        mHeightGap = heightGap;
2998245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mChildren.setGap(widthGap, heightGap);
300df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung    }
301df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung
30280baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    public int[] getCellCountForDimensions(int width, int height) {
30380baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        // Always assume we're working with the smallest span to make sure we
30480baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        // reserve enough space in both orientations
30580baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        int smallerSize = Math.min(mCellWidth, mCellHeight);
30680baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
30780baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        // Always round up to next largest cell
30880baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        int spanX = (width + smallerSize) / smallerSize;
30980baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        int spanY = (height + smallerSize) / smallerSize;
31080baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
31180baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        return new int[] { spanX, spanY };
31280baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    }
31380baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
314321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    /**
315321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung     * Start dragging the specified child
316321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung     *
317321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung     * @param child The child that is being dragged
318321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung     */
319321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    void onDragChild(View child) {
320321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        PagedViewCellLayout.LayoutParams lp = (PagedViewCellLayout.LayoutParams) child.getLayoutParams();
321321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        lp.isDragging = true;
322321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
323321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
324e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    /**
325e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung     * Estimates the number of cells that the specified width would take up.
326e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung     */
32780baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    public int estimateCellHSpan(int width) {
328f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        // The space for a page assuming that we want to show half of a column of the previous and
329f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        // next pages is the width - left padding (current & next page) - right padding (previous &
330f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        // current page) - half cell width (for previous and next pages)
331c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung        int availWidth = (int) (width - (2 * mPaddingLeft + 2 * mPaddingRight));
332f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung
333f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        // We know that we have to fit N cells with N-1 width gaps, so we just juggle to solve for N
334f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        int n = Math.max(1, (availWidth + mWidthGap) / (mCellWidth + mWidthGap));
335f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung
336f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        // We don't do anything fancy to determine if we squeeze another row in.
337f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        return n;
33880baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    }
339e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung
340e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    /**
341e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung     * Estimates the number of cells that the specified height would take up.
342e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung     */
34380baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    public int estimateCellVSpan(int height) {
344f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        // The space for a page is the height - top padding (current page) - bottom padding (current
345f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        // page)
346f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        int availHeight = height - (mPaddingTop + mPaddingBottom);
347f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung
348f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        // We know that we have to fit N cells with N-1 height gaps, so we juggle to solve for N
349f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        int n = Math.max(1, (availHeight + mHeightGap) / (mCellHeight + mHeightGap));
350f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung
351f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        // We don't do anything fancy to determine if we squeeze another row in.
352f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        return n;
353f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung    }
354f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung
3557d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung    /** Returns an estimated center position of the cell at the specified index */
3567d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung    public int[] estimateCellPosition(int x, int y) {
3577d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung        return new int[] {
3587d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung                mPaddingLeft + (x * mCellWidth) + (x * mWidthGap) + (mCellWidth / 2),
3597d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung                mPaddingTop + (y * mCellHeight) + (y * mHeightGap) + (mCellHeight / 2)
3607d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung        };
3617d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung    }
3627d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung
363f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung    public void calculateCellCount(int width, int height, int maxCellCountX, int maxCellCountY) {
364f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        mCellCountX = Math.min(maxCellCountX, estimateCellHSpan(width));
365f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        mCellCountY = Math.min(maxCellCountY, estimateCellVSpan(height));
366f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        requestLayout();
36780baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    }
368e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung
369e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    /**
370e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung     * Estimates the width that the number of vSpan cells will take up.
371e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung     */
372e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    public int estimateCellWidth(int hSpan) {
373e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung        // TODO: we need to take widthGap into effect
374e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung        return hSpan * mCellWidth;
375e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    }
376e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung
377e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    /**
378e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung     * Estimates the height that the number of vSpan cells will take up.
379e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung     */
380e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    public int estimateCellHeight(int vSpan) {
381e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung        // TODO: we need to take heightGap into effect
382e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung        return vSpan * mCellHeight;
38380baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    }
38480baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
385321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
386321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
387321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        return new PagedViewCellLayout.LayoutParams(getContext(), attrs);
388321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
389321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
390321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
391321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
392321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        return p instanceof PagedViewCellLayout.LayoutParams;
393321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
394321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
395321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
396321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
397321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        return new PagedViewCellLayout.LayoutParams(p);
398321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
399321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
400321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    public static class LayoutParams extends ViewGroup.MarginLayoutParams {
401321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        /**
402321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         * Horizontal location of the item in the grid.
403321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         */
404321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        @ViewDebug.ExportedProperty
405321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public int cellX;
406321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
407321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        /**
408321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         * Vertical location of the item in the grid.
409321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         */
410321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        @ViewDebug.ExportedProperty
411321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public int cellY;
412321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
413321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        /**
414321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         * Number of cells spanned horizontally by the item.
415321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         */
416321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        @ViewDebug.ExportedProperty
417321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public int cellHSpan;
418321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
419321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        /**
420321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         * Number of cells spanned vertically by the item.
421321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         */
422321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        @ViewDebug.ExportedProperty
423321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public int cellVSpan;
424321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
425321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        /**
426321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         * Is this item currently being dragged
427321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         */
428321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public boolean isDragging;
429321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
43080baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        // a data object that you can bind to this layout params
43180baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        private Object mTag;
43280baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
433321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        // X coordinate of the view in the layout.
434321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        @ViewDebug.ExportedProperty
435321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int x;
436321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        // Y coordinate of the view in the layout.
437321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        @ViewDebug.ExportedProperty
438321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int y;
439321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
44080baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        public LayoutParams() {
44180baf5a6b3c62a62265f626d43d1167783c94131Winson Chung            super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
44280baf5a6b3c62a62265f626d43d1167783c94131Winson Chung            cellHSpan = 1;
44380baf5a6b3c62a62265f626d43d1167783c94131Winson Chung            cellVSpan = 1;
44480baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        }
44580baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
446321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public LayoutParams(Context c, AttributeSet attrs) {
447321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            super(c, attrs);
448321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            cellHSpan = 1;
449321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            cellVSpan = 1;
450321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
451321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
452321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public LayoutParams(ViewGroup.LayoutParams source) {
453321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            super(source);
454321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            cellHSpan = 1;
455321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            cellVSpan = 1;
456321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
457321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
458321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public LayoutParams(LayoutParams source) {
459321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            super(source);
460321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            this.cellX = source.cellX;
461321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            this.cellY = source.cellY;
462321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            this.cellHSpan = source.cellHSpan;
463321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            this.cellVSpan = source.cellVSpan;
464321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
465321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
466321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public LayoutParams(int cellX, int cellY, int cellHSpan, int cellVSpan) {
467321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
468321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            this.cellX = cellX;
469321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            this.cellY = cellY;
470321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            this.cellHSpan = cellHSpan;
471321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            this.cellVSpan = cellVSpan;
472321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
473321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
474321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public void setup(int cellWidth, int cellHeight, int widthGap, int heightGap,
475321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung                int hStartPadding, int vStartPadding) {
476321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
477321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            final int myCellHSpan = cellHSpan;
478321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            final int myCellVSpan = cellVSpan;
479321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            final int myCellX = cellX;
480321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            final int myCellY = cellY;
481321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
482321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            width = myCellHSpan * cellWidth + ((myCellHSpan - 1) * widthGap) -
483321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung                    leftMargin - rightMargin;
484321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            height = myCellVSpan * cellHeight + ((myCellVSpan - 1) * heightGap) -
485321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung                    topMargin - bottomMargin;
486321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
487a2eb17095dcffa75c1e9681fdc318fe6e0564321Michael Jurka            if (LauncherApplication.isScreenLarge()) {
488785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung                x = hStartPadding + myCellX * (cellWidth + widthGap) + leftMargin;
489785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung                y = vStartPadding + myCellY * (cellHeight + heightGap) + topMargin;
490785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung            } else {
491785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung                x = myCellX * (cellWidth + widthGap) + leftMargin;
492785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung                y = myCellY * (cellHeight + heightGap) + topMargin;
493785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung            }
494321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
495321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
49680baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        public Object getTag() {
49780baf5a6b3c62a62265f626d43d1167783c94131Winson Chung            return mTag;
49880baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        }
49980baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
50080baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        public void setTag(Object tag) {
50180baf5a6b3c62a62265f626d43d1167783c94131Winson Chung            mTag = tag;
50280baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        }
50380baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
504321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public String toString() {
50580baf5a6b3c62a62265f626d43d1167783c94131Winson Chung            return "(" + this.cellX + ", " + this.cellY + ", " +
50680baf5a6b3c62a62265f626d43d1167783c94131Winson Chung                this.cellHSpan + ", " + this.cellVSpan + ")";
507321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
508321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
509321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung}
5108245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka
5118245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurkainterface Page {
5128245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public int getPageChildCount();
5138245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public View getChildOnPageAt(int i);
5148245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public void removeAllViewsOnPage();
5158245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public void removeViewOnPageAt(int i);
5168245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public int indexOfChildOnPage(View v);
5178245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka}
518