PagedViewCellLayout.java revision abded66084680bb31cc7ea403c88f44f79a3c884
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;
20321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chungimport android.util.AttributeSet;
21321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chungimport android.view.MotionEvent;
22321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chungimport android.view.View;
23321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chungimport android.view.ViewDebug;
24321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chungimport android.view.ViewGroup;
25321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
26321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung/**
27321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * An abstraction of the original CellLayout which supports laying out items
28321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * which span multiple cells into a grid-like layout.  Also supports dimming
29321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung * to give a preview of its contents.
30321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung */
318245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurkapublic class PagedViewCellLayout extends ViewGroup implements Page {
32321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    static final String TAG = "PagedViewCellLayout";
33321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
34321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    private int mCellCountX;
35321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    private int mCellCountY;
36321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    private int mCellWidth;
37321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    private int mCellHeight;
38df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung    private int mWidthGap;
39df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung    private int mHeightGap;
40321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    private static int sDefaultCellDimensions = 96;
418245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    protected PagedViewCellLayoutChildren mChildren;
428245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    private PagedViewCellLayoutChildren mHolographicChildren;
43abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka    private boolean mAllowHardwareLayerCreation = false;
44abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka    private boolean mCreateHardwareLayersIfAllowed = false;
45321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
46321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    public PagedViewCellLayout(Context context) {
47321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        this(context, null);
48321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
49321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
50321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    public PagedViewCellLayout(Context context, AttributeSet attrs) {
51321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        this(context, attrs, 0);
52321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
53321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
54321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    public PagedViewCellLayout(Context context, AttributeSet attrs, int defStyle) {
55321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        super(context, attrs, defStyle);
56321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
57321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        setAlwaysDrawnWithCacheEnabled(false);
58321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
59321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        // setup default cell parameters
60321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        mCellWidth = mCellHeight = sDefaultCellDimensions;
61321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        mCellCountX = LauncherModel.getCellCountX();
62321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        mCellCountY = LauncherModel.getCellCountY();
63df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung        mWidthGap = mHeightGap = -1;
64321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
658245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mChildren = new PagedViewCellLayoutChildren(context);
668245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mChildren.setCellDimensions(mCellWidth, mCellHeight);
678245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mChildren.setGap(mWidthGap, mHeightGap);
688245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka
698245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        addView(mChildren);
708245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mHolographicChildren = new PagedViewCellLayoutChildren(context);
718245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mHolographicChildren.setAlpha(0f);
728245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mHolographicChildren.setCellDimensions(mCellWidth, mCellHeight);
738245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mHolographicChildren.setGap(mWidthGap, mHeightGap);
748245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka
758245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        addView(mHolographicChildren);
76321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
77321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
78abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka    public void allowHardwareLayerCreation() {
79abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka        // This is called after the first time we launch into All Apps. Before that point,
80abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka        // there's no need for hardware layers here since there's a hardware layer set on the
81abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka        // parent, AllAppsTabbed, during the AllApps transition -- creating hardware layers here
82abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka        // before the animation is done slows down the animation
83abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka        if (!mAllowHardwareLayerCreation) {
84abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka            mAllowHardwareLayerCreation = true;
85abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka            if (mCreateHardwareLayersIfAllowed) {
86abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka                createHardwareLayers();
87abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka            }
88abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka        }
89c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka    }
90c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka
91321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
92b3347bb9f4ccf41fb7043bca66c3a565bde1083bWinson Chung    public void setAlpha(float alpha) {
938245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mChildren.setAlpha(alpha);
948245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mHolographicChildren.setAlpha(1.0f - alpha);
95321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
96321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
97c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka    void destroyHardwareLayers() {
98abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka        // called when a page is no longer visible (triggered by loadAssociatedPages ->
99abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka        // removeAllViewsOnPage)
100abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka        mCreateHardwareLayersIfAllowed = false;
101abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka        if (mAllowHardwareLayerCreation) {
102c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka            mChildren.destroyHardwareLayer();
103c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka            mHolographicChildren.destroyHardwareLayer();
104c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka        }
105c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka    }
106c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka    void createHardwareLayers() {
107abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka        // called when a page is visible (triggered by loadAssociatedPages -> syncPageItems)
108abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka        mCreateHardwareLayersIfAllowed = true;
109abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka        if (mAllowHardwareLayerCreation) {
110c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka            mChildren.createHardwareLayer();
111c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka            mHolographicChildren.createHardwareLayer();
112c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka        }
113c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka    }
114c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka
115321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
116321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    public void cancelLongPress() {
117321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        super.cancelLongPress();
118321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
119321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        // Cancel long press for all children
120321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        final int count = getChildCount();
121321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        for (int i = 0; i < count; i++) {
122321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            final View child = getChildAt(i);
123321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            child.cancelLongPress();
124321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
125321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
126321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
127321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    public boolean addViewToCellLayout(View child, int index, int childId,
128321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            PagedViewCellLayout.LayoutParams params) {
129321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        final PagedViewCellLayout.LayoutParams lp = params;
130321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
131321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        // Generate an id for each view, this assumes we have at most 256x256 cells
132321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        // per workspace screen
133321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        if (lp.cellX >= 0 && lp.cellX <= (mCellCountX - 1) &&
134321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung                lp.cellY >= 0 && (lp.cellY <= mCellCountY - 1)) {
135321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            // If the horizontal or vertical span is set to -1, it is taken to
136321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            // mean that it spans the extent of the CellLayout
137321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            if (lp.cellHSpan < 0) lp.cellHSpan = mCellCountX;
138321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            if (lp.cellVSpan < 0) lp.cellVSpan = mCellCountY;
139321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
140321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            child.setId(childId);
1418245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka            mChildren.addView(child, index, lp);
142321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
1438245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka            if (child instanceof PagedViewIcon) {
1448245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka                PagedViewIcon pagedViewIcon = (PagedViewIcon) child;
145abded66084680bb31cc7ea403c88f44f79a3c884Michael Jurka                if (mAllowHardwareLayerCreation) {
146c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka                    pagedViewIcon.disableCache();
147c0759f5090d9539d82ddc944b9f2da767c36b251Michael Jurka                }
1488245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka                mHolographicChildren.addView(pagedViewIcon.getHolographicOutlineView(), index, lp);
1498245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka            }
150321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            return true;
151321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
152321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        return false;
153321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
154321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
155321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
1568245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public void removeAllViewsOnPage() {
1578245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mChildren.removeAllViews();
1588245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mHolographicChildren.removeAllViews();
159c5e49022bea70a1b0b6ada5431afbb6e951cc3f6Michael Jurka        destroyHardwareLayers();
160321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
161321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
162321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
1638245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public void removeViewOnPageAt(int index) {
1648245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mChildren.removeViewAt(index);
1658245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mHolographicChildren.removeViewAt(index);
1668245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    }
1678245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka
1688245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    @Override
1698245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public int getPageChildCount() {
1708245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        return mChildren.getChildCount();
1718245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    }
1728245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka
1738245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    @Override
1748245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public View getChildOnPageAt(int i) {
1758245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        return mChildren.getChildAt(i);
1768245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    }
1778245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka
1788245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    @Override
1798245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public int indexOfChildOnPage(View v) {
1808245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        return mChildren.indexOfChild(v);
1818245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    }
1828245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka
183321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
184321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        // TODO: currently ignoring padding
185321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
186321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
187321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
188321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
189321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
190321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int heightSpecSize =  MeasureSpec.getSize(heightMeasureSpec);
191321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
192321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        if (widthSpecMode == MeasureSpec.UNSPECIFIED || heightSpecMode == MeasureSpec.UNSPECIFIED) {
193321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            throw new RuntimeException("CellLayout cannot have UNSPECIFIED dimensions");
194321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
195321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
196321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        final int cellWidth = mCellWidth;
197321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        final int cellHeight = mCellHeight;
198321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
199321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int numWidthGaps = mCellCountX - 1;
200321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int numHeightGaps = mCellCountY - 1;
201321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
202321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int vSpaceLeft = heightSpecSize - mPaddingTop
203321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung                - mPaddingBottom - (cellHeight * mCellCountY);
204321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int heightGap = vSpaceLeft / numHeightGaps;
205321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
206321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int hSpaceLeft = widthSpecSize - mPaddingLeft
207321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung                - mPaddingRight - (cellWidth * mCellCountX);
208321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int widthGap = hSpaceLeft / numWidthGaps;
209321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
210321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        // center it around the min gaps
211321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int minGap = Math.min(widthGap, heightGap);
212321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        /*
213321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        if (minGap < heightGap) {
214321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            // vertical space has shrunken, so change padding accordingly
215321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            paddingTop += ((heightGap - minGap) * (mCellCountY - 1)) / 2;
216321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        } else if (minGap < widthGap) {
217321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            // horizontal space has shrunken, so change padding accordingly
218321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            paddingLeft += ((widthGap - minGap) * (mCellCountX - 1)) / 2;
219321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
220321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        */
221df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung        if (mWidthGap > -1 && mHeightGap > -1) {
222df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung            widthGap = mWidthGap;
223df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung            heightGap = mHeightGap;
224df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung        } else {
225df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung            widthGap = heightGap = minGap;
226df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung        }
227321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
228321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int newWidth = mPaddingLeft + mPaddingRight + (mCellCountX * cellWidth) +
229df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung            ((mCellCountX - 1) * widthGap);
230321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int newHeight = mPaddingTop + mPaddingBottom + (mCellCountY * cellHeight) +
231df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung            ((mCellCountY - 1) * heightGap);
232321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
233321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        final int count = getChildCount();
234321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        for (int i = 0; i < count; i++) {
235321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            View child = getChildAt(i);
2368245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka            int childWidthMeasureSpec =
2378245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka                MeasureSpec.makeMeasureSpec(newWidth, MeasureSpec.EXACTLY);
2388245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka            int childheightMeasureSpec =
2398245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka                MeasureSpec.makeMeasureSpec(newHeight, MeasureSpec.EXACTLY);
240321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            child.measure(childWidthMeasureSpec, childheightMeasureSpec);
241321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
242321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
243321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        setMeasuredDimension(newWidth, newHeight);
244321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
245321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
246321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
247321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    protected void onLayout(boolean changed, int l, int t, int r, int b) {
248321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int count = getChildCount();
249321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        for (int i = 0; i < count; i++) {
250321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            View child = getChildAt(i);
2518245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka            child.layout(0, 0, r - l, b - t);
252321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
253321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
254321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
255321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
256321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    public boolean onTouchEvent(MotionEvent event) {
257321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        return super.onTouchEvent(event) || true;
258321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
259321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
26080baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    public void enableCenteredContent(boolean enabled) {
2618245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mChildren.enableCenteredContent(enabled);
2628245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mHolographicChildren.enableCenteredContent(enabled);
26380baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    }
26480baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
265321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
266321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    protected void setChildrenDrawingCacheEnabled(boolean enabled) {
2678245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mChildren.setChildrenDrawingCacheEnabled(enabled);
2688245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mHolographicChildren.setChildrenDrawingCacheEnabled(enabled);
269321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
270321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
271321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    public void setCellCount(int xCount, int yCount) {
272321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        mCellCountX = xCount;
273321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        mCellCountY = yCount;
274321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        requestLayout();
275321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
276321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
277df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung    public void setGap(int widthGap, int heightGap) {
278df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung        mWidthGap = widthGap;
279df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung        mHeightGap = heightGap;
2808245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mChildren.setGap(widthGap, heightGap);
2818245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mHolographicChildren.setGap(widthGap, heightGap);
282df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung    }
283df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung
284e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    public void setCellDimensions(int width, int height) {
285e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung        mCellWidth = width;
286e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung        mCellHeight = height;
2878245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mChildren.setCellDimensions(width, height);
2888245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mHolographicChildren.setCellDimensions(width, height);
289e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    }
290e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung
291e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    public int getDefaultCellDimensions() {
292e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung        return sDefaultCellDimensions;
293e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    }
294e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung
29580baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    public int[] getCellCountForDimensions(int width, int height) {
29680baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        // Always assume we're working with the smallest span to make sure we
29780baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        // reserve enough space in both orientations
29880baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        int smallerSize = Math.min(mCellWidth, mCellHeight);
29980baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
30080baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        // Always round up to next largest cell
30180baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        int spanX = (width + smallerSize) / smallerSize;
30280baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        int spanY = (height + smallerSize) / smallerSize;
30380baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
30480baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        return new int[] { spanX, spanY };
30580baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    }
30680baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
307321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    /**
308321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung     * Start dragging the specified child
309321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung     *
310321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung     * @param child The child that is being dragged
311321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung     */
312321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    void onDragChild(View child) {
313321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        PagedViewCellLayout.LayoutParams lp = (PagedViewCellLayout.LayoutParams) child.getLayoutParams();
314321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        lp.isDragging = true;
315321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
316321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
317e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    /**
318e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung     * Estimates the number of cells that the specified width would take up.
319e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung     */
32080baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    public int estimateCellHSpan(int width) {
321e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung        // TODO: we need to take widthGap into effect
32280baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        return (width + mCellWidth) / mCellWidth;
32380baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    }
324e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung
325e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    /**
326e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung     * Estimates the number of cells that the specified height would take up.
327e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung     */
32880baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    public int estimateCellVSpan(int height) {
329e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung        // TODO: we need to take heightGap into effect
33080baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        return (height + mCellHeight) / mCellHeight;
33180baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    }
332e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung
333e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    /**
334e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung     * Estimates the width that the number of vSpan cells will take up.
335e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung     */
336e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    public int estimateCellWidth(int hSpan) {
337e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung        // TODO: we need to take widthGap into effect
338e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung        return hSpan * mCellWidth;
339e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    }
340e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung
341e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    /**
342e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung     * Estimates the height that the number of vSpan cells will take up.
343e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung     */
344e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    public int estimateCellHeight(int vSpan) {
345e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung        // TODO: we need to take heightGap into effect
346e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung        return vSpan * mCellHeight;
34780baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    }
34880baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
349321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
350321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
351321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        return new PagedViewCellLayout.LayoutParams(getContext(), attrs);
352321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
353321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
354321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
355321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
356321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        return p instanceof PagedViewCellLayout.LayoutParams;
357321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
358321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
359321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
360321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
361321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        return new PagedViewCellLayout.LayoutParams(p);
362321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
363321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
364321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    public static class LayoutParams extends ViewGroup.MarginLayoutParams {
365321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        /**
366321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         * Horizontal location of the item in the grid.
367321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         */
368321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        @ViewDebug.ExportedProperty
369321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public int cellX;
370321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
371321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        /**
372321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         * Vertical location of the item in the grid.
373321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         */
374321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        @ViewDebug.ExportedProperty
375321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public int cellY;
376321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
377321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        /**
378321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         * Number of cells spanned horizontally by the item.
379321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         */
380321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        @ViewDebug.ExportedProperty
381321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public int cellHSpan;
382321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
383321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        /**
384321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         * Number of cells spanned vertically by the item.
385321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         */
386321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        @ViewDebug.ExportedProperty
387321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public int cellVSpan;
388321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
389321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        /**
390321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         * Is this item currently being dragged
391321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         */
392321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public boolean isDragging;
393321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
39480baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        // a data object that you can bind to this layout params
39580baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        private Object mTag;
39680baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
397321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        // X coordinate of the view in the layout.
398321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        @ViewDebug.ExportedProperty
399321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int x;
400321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        // Y coordinate of the view in the layout.
401321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        @ViewDebug.ExportedProperty
402321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int y;
403321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
40480baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        public LayoutParams() {
40580baf5a6b3c62a62265f626d43d1167783c94131Winson Chung            super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
40680baf5a6b3c62a62265f626d43d1167783c94131Winson Chung            cellHSpan = 1;
40780baf5a6b3c62a62265f626d43d1167783c94131Winson Chung            cellVSpan = 1;
40880baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        }
40980baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
410321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public LayoutParams(Context c, AttributeSet attrs) {
411321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            super(c, attrs);
412321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            cellHSpan = 1;
413321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            cellVSpan = 1;
414321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
415321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
416321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public LayoutParams(ViewGroup.LayoutParams source) {
417321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            super(source);
418321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            cellHSpan = 1;
419321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            cellVSpan = 1;
420321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
421321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
422321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public LayoutParams(LayoutParams source) {
423321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            super(source);
424321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            this.cellX = source.cellX;
425321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            this.cellY = source.cellY;
426321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            this.cellHSpan = source.cellHSpan;
427321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            this.cellVSpan = source.cellVSpan;
428321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
429321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
430321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public LayoutParams(int cellX, int cellY, int cellHSpan, int cellVSpan) {
431321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
432321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            this.cellX = cellX;
433321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            this.cellY = cellY;
434321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            this.cellHSpan = cellHSpan;
435321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            this.cellVSpan = cellVSpan;
436321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
437321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
438321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public void setup(int cellWidth, int cellHeight, int widthGap, int heightGap,
439321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung                int hStartPadding, int vStartPadding) {
440321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
441321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            final int myCellHSpan = cellHSpan;
442321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            final int myCellVSpan = cellVSpan;
443321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            final int myCellX = cellX;
444321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            final int myCellY = cellY;
445321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
446321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            width = myCellHSpan * cellWidth + ((myCellHSpan - 1) * widthGap) -
447321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung                    leftMargin - rightMargin;
448321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            height = myCellVSpan * cellHeight + ((myCellVSpan - 1) * heightGap) -
449321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung                    topMargin - bottomMargin;
450321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
451321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            x = hStartPadding + myCellX * (cellWidth + widthGap) + leftMargin;
452321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            y = vStartPadding + myCellY * (cellHeight + heightGap) + topMargin;
453321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
454321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
45580baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        public Object getTag() {
45680baf5a6b3c62a62265f626d43d1167783c94131Winson Chung            return mTag;
45780baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        }
45880baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
45980baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        public void setTag(Object tag) {
46080baf5a6b3c62a62265f626d43d1167783c94131Winson Chung            mTag = tag;
46180baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        }
46280baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
463321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public String toString() {
46480baf5a6b3c62a62265f626d43d1167783c94131Winson Chung            return "(" + this.cellX + ", " + this.cellY + ", " +
46580baf5a6b3c62a62265f626d43d1167783c94131Winson Chung                this.cellHSpan + ", " + this.cellVSpan + ")";
466321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
467321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
468321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung}
4698245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka
4708245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurkainterface Page {
4718245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public int getPageChildCount();
4728245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public View getChildOnPageAt(int i);
4738245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public void removeAllViewsOnPage();
4748245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public void removeViewOnPageAt(int i);
4758245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public int indexOfChildOnPage(View v);
4768245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka}
477