PagedViewCellLayout.java revision d92e741ca67c58c4be01a64940847feafe26a4b1
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
2467ef959b9177e1e715b0afe010904455a3d961fc4Michael Jurka    int getContentWidth() {
2477ef959b9177e1e715b0afe010904455a3d961fc4Michael Jurka        // Return the distance from the left edge of the content of the leftmost icon to
2487ef959b9177e1e715b0afe010904455a3d961fc4Michael Jurka        // the right edge of the content of the rightmost icon
2497ef959b9177e1e715b0afe010904455a3d961fc4Michael Jurka
2500413dfa01b822e349092636774dc948b9230adeaMichael Jurka        // icons are centered within cells, find out how much padding that accounts for
251d92e741ca67c58c4be01a64940847feafe26a4b1Michael Jurka        return getWidthBeforeFirstLayout() - (mCellWidth - Utilities.getIconContentSize());
2520413dfa01b822e349092636774dc948b9230adeaMichael Jurka    }
2530413dfa01b822e349092636774dc948b9230adeaMichael Jurka
254d92e741ca67c58c4be01a64940847feafe26a4b1Michael Jurka    int getWidthBeforeFirstLayout() {
2550413dfa01b822e349092636774dc948b9230adeaMichael Jurka        return mCellCountX * mCellWidth + (mCellCountX - 1) * mWidthGap;
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);
2638245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka            child.layout(0, 0, r - l, b - t);
264321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
265321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
266321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
267321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
268321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    public boolean onTouchEvent(MotionEvent event) {
269321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        return super.onTouchEvent(event) || true;
270321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
271321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
27280baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    public void enableCenteredContent(boolean enabled) {
2738245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mChildren.enableCenteredContent(enabled);
2748245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mHolographicChildren.enableCenteredContent(enabled);
27580baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    }
27680baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
277321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
278321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    protected void setChildrenDrawingCacheEnabled(boolean enabled) {
2798245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mChildren.setChildrenDrawingCacheEnabled(enabled);
2808245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mHolographicChildren.setChildrenDrawingCacheEnabled(enabled);
281321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
282321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
283321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    public void setCellCount(int xCount, int yCount) {
284321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        mCellCountX = xCount;
285321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        mCellCountY = yCount;
286321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        requestLayout();
287321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
288321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
289df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung    public void setGap(int widthGap, int heightGap) {
290df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung        mWidthGap = widthGap;
291df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung        mHeightGap = heightGap;
2928245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mChildren.setGap(widthGap, heightGap);
2938245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka        mHolographicChildren.setGap(widthGap, heightGap);
294df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung    }
295df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung
29680baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    public int[] getCellCountForDimensions(int width, int height) {
29780baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        // Always assume we're working with the smallest span to make sure we
29880baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        // reserve enough space in both orientations
29980baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        int smallerSize = Math.min(mCellWidth, mCellHeight);
30080baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
30180baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        // Always round up to next largest cell
30280baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        int spanX = (width + smallerSize) / smallerSize;
30380baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        int spanY = (height + smallerSize) / smallerSize;
30480baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
30580baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        return new int[] { spanX, spanY };
30680baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    }
30780baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
308321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    /**
309321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung     * Start dragging the specified child
310321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung     *
311321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung     * @param child The child that is being dragged
312321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung     */
313321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    void onDragChild(View child) {
314321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        PagedViewCellLayout.LayoutParams lp = (PagedViewCellLayout.LayoutParams) child.getLayoutParams();
315321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        lp.isDragging = true;
316321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
317321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
318e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    /**
319e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung     * Estimates the number of cells that the specified width would take up.
320e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung     */
32180baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    public int estimateCellHSpan(int width) {
322e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung        // TODO: we need to take widthGap into effect
32380baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        return (width + mCellWidth) / mCellWidth;
32480baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    }
325e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung
326e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    /**
327e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung     * Estimates the number of cells that the specified height would take up.
328e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung     */
32980baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    public int estimateCellVSpan(int height) {
330e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung        // TODO: we need to take heightGap into effect
33180baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        return (height + mCellHeight) / mCellHeight;
33280baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    }
333e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung
334e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    /**
335e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung     * Estimates the width that the number of vSpan cells will take up.
336e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung     */
337e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    public int estimateCellWidth(int hSpan) {
338e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung        // TODO: we need to take widthGap into effect
339e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung        return hSpan * mCellWidth;
340e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    }
341e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung
342e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    /**
343e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung     * Estimates the height that the number of vSpan cells will take up.
344e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung     */
345e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung    public int estimateCellHeight(int vSpan) {
346e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung        // TODO: we need to take heightGap into effect
347e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung        return vSpan * mCellHeight;
34880baf5a6b3c62a62265f626d43d1167783c94131Winson Chung    }
34980baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
350321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
351321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
352321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        return new PagedViewCellLayout.LayoutParams(getContext(), attrs);
353321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
354321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
355321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
356321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
357321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        return p instanceof PagedViewCellLayout.LayoutParams;
358321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
359321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
360321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    @Override
361321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
362321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        return new PagedViewCellLayout.LayoutParams(p);
363321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
364321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
365321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    public static class LayoutParams extends ViewGroup.MarginLayoutParams {
366321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        /**
367321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         * Horizontal location of the item in the grid.
368321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         */
369321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        @ViewDebug.ExportedProperty
370321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public int cellX;
371321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
372321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        /**
373321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         * Vertical location of the item in the grid.
374321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         */
375321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        @ViewDebug.ExportedProperty
376321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public int cellY;
377321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
378321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        /**
379321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         * Number of cells spanned horizontally by the item.
380321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         */
381321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        @ViewDebug.ExportedProperty
382321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public int cellHSpan;
383321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
384321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        /**
385321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         * Number of cells spanned vertically by the item.
386321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         */
387321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        @ViewDebug.ExportedProperty
388321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public int cellVSpan;
389321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
390321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        /**
391321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         * Is this item currently being dragged
392321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung         */
393321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public boolean isDragging;
394321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
39580baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        // a data object that you can bind to this layout params
39680baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        private Object mTag;
39780baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
398321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        // X coordinate of the view in the layout.
399321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        @ViewDebug.ExportedProperty
400321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int x;
401321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        // Y coordinate of the view in the layout.
402321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        @ViewDebug.ExportedProperty
403321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        int y;
404321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
40580baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        public LayoutParams() {
40680baf5a6b3c62a62265f626d43d1167783c94131Winson Chung            super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
40780baf5a6b3c62a62265f626d43d1167783c94131Winson Chung            cellHSpan = 1;
40880baf5a6b3c62a62265f626d43d1167783c94131Winson Chung            cellVSpan = 1;
40980baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        }
41080baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
411321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public LayoutParams(Context c, AttributeSet attrs) {
412321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            super(c, attrs);
413321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            cellHSpan = 1;
414321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            cellVSpan = 1;
415321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
416321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
417321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public LayoutParams(ViewGroup.LayoutParams source) {
418321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            super(source);
419321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            cellHSpan = 1;
420321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            cellVSpan = 1;
421321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
422321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
423321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public LayoutParams(LayoutParams source) {
424321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            super(source);
425321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            this.cellX = source.cellX;
426321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            this.cellY = source.cellY;
427321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            this.cellHSpan = source.cellHSpan;
428321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            this.cellVSpan = source.cellVSpan;
429321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
430321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
431321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public LayoutParams(int cellX, int cellY, int cellHSpan, int cellVSpan) {
432321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
433321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            this.cellX = cellX;
434321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            this.cellY = cellY;
435321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            this.cellHSpan = cellHSpan;
436321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            this.cellVSpan = cellVSpan;
437321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
438321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
439321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public void setup(int cellWidth, int cellHeight, int widthGap, int heightGap,
440321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung                int hStartPadding, int vStartPadding) {
441321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
442321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            final int myCellHSpan = cellHSpan;
443321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            final int myCellVSpan = cellVSpan;
444321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            final int myCellX = cellX;
445321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            final int myCellY = cellY;
446321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
447321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            width = myCellHSpan * cellWidth + ((myCellHSpan - 1) * widthGap) -
448321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung                    leftMargin - rightMargin;
449321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            height = myCellVSpan * cellHeight + ((myCellVSpan - 1) * heightGap) -
450321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung                    topMargin - bottomMargin;
451321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
452321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            x = hStartPadding + myCellX * (cellWidth + widthGap) + leftMargin;
453321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung            y = vStartPadding + myCellY * (cellHeight + heightGap) + topMargin;
454321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
455321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung
45680baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        public Object getTag() {
45780baf5a6b3c62a62265f626d43d1167783c94131Winson Chung            return mTag;
45880baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        }
45980baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
46080baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        public void setTag(Object tag) {
46180baf5a6b3c62a62265f626d43d1167783c94131Winson Chung            mTag = tag;
46280baf5a6b3c62a62265f626d43d1167783c94131Winson Chung        }
46380baf5a6b3c62a62265f626d43d1167783c94131Winson Chung
464321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        public String toString() {
46580baf5a6b3c62a62265f626d43d1167783c94131Winson Chung            return "(" + this.cellX + ", " + this.cellY + ", " +
46680baf5a6b3c62a62265f626d43d1167783c94131Winson Chung                this.cellHSpan + ", " + this.cellVSpan + ")";
467321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung        }
468321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung    }
469321e9ee68848d9e782fd557f69cc070308ffbc9cWinson Chung}
4708245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka
4718245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurkainterface Page {
4728245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public int getPageChildCount();
4738245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public View getChildOnPageAt(int i);
4748245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public void removeAllViewsOnPage();
4758245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public void removeViewOnPageAt(int i);
4768245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka    public int indexOfChildOnPage(View v);
4778245a8685fc9f4802c9fa29a989854b2522fc588Michael Jurka}
478